Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c8ff453b6e
7 changed files with 504 additions and 124 deletions
|
@ -47,7 +47,7 @@ public class Amenity extends MapObject {
|
|||
this.site = entity.getTag(OSMTagKey.CONTACT_WEBSITE);
|
||||
}
|
||||
}
|
||||
if (this.site.indexOf("://") == -1){
|
||||
if (this.site != null && !this.site.startsWith("http://")){
|
||||
this.site = "http://"+this.site;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +1,275 @@
|
|||
package net.osmand.osm;
|
||||
|
||||
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Class used to parse opening hours
|
||||
*
|
||||
* the method "parseOpenedHours" will parse an OSM opening_hours string and return
|
||||
* an object of the type OpeningHours. That object can be used to check if the OSM feature
|
||||
* is open at a certain time.
|
||||
*/
|
||||
public class OpeningHoursParser {
|
||||
private static final String[] daysStr = new String[] {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
|
||||
/**
|
||||
* default values for sunrise and sunset. Might be computed afterwards, not final
|
||||
*/
|
||||
private static String sunrise = "07:00", sunset = "21:00";
|
||||
/**
|
||||
* hour of when you would expect a day to be ended.
|
||||
* This is to be used when no end hour is known (like pubs that open at a certain time,
|
||||
* but close at a variable time, depending on the number of clients).
|
||||
* OsmAnd needs to show a value, so there is some arbitrary default value chosen.
|
||||
*/
|
||||
private static String endOfDay = "24:00";
|
||||
|
||||
/**
|
||||
* This class contains the entire OpeningHours schema and
|
||||
* offers methods to check directly weather something is open
|
||||
*
|
||||
* @author sander
|
||||
*/
|
||||
public static class OpeningHours {
|
||||
|
||||
/**
|
||||
* list of the different rules
|
||||
*/
|
||||
private ArrayList<OpeningHoursRule> rules;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param rules List of OpeningHoursRule to be given
|
||||
*/
|
||||
public OpeningHours(ArrayList<OpeningHoursRule> rules) {
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty constructor
|
||||
*/
|
||||
public OpeningHours(){
|
||||
rules = new ArrayList<OpeningHoursRule>();
|
||||
}
|
||||
|
||||
/**
|
||||
* add a rule to the opening hours
|
||||
* @param r rule to add
|
||||
*/
|
||||
public void addRule(OpeningHoursRule r){
|
||||
rules.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the list of rules
|
||||
*
|
||||
* @return the rules
|
||||
*/
|
||||
public ArrayList<OpeningHoursRule> getRules(){
|
||||
return rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the feature is opened at time "cal"
|
||||
* @param cal the time to check
|
||||
* @return true if feature is open
|
||||
*/
|
||||
public boolean isOpenedForTime(Calendar cal){
|
||||
/*
|
||||
* first check for rules that contain the current day
|
||||
* afterwards check for rules that contain the previous
|
||||
* day with overlapping times (times after midnight)
|
||||
*/
|
||||
boolean isOpenDay = false;
|
||||
for (OpeningHoursRule r : rules){
|
||||
if(r.containsDay(cal)){
|
||||
isOpenDay = r.isOpenedForTime(cal, false);
|
||||
}
|
||||
}
|
||||
boolean isOpenPrevious = false;
|
||||
for (OpeningHoursRule r : rules){
|
||||
if(r.containsPreviousDay(cal)){
|
||||
isOpenPrevious = r.isOpenedForTime(cal, true);
|
||||
}
|
||||
}
|
||||
return isOpenDay || isOpenPrevious;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
if (rules.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
for (OpeningHoursRule r : rules) {
|
||||
s.append(r.toString()).append("; ");
|
||||
}
|
||||
|
||||
return s.substring(0, s.length()-2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to represent a single rule
|
||||
*
|
||||
* A rule consist out of
|
||||
* - a collection of days/dates
|
||||
* - a time range
|
||||
*/
|
||||
public static interface OpeningHoursRule {
|
||||
|
||||
public boolean isOpenedForTime(Calendar cal);
|
||||
/**
|
||||
* Check if, for this rule, the feature is opened for time "cal"
|
||||
* @param cal the time to check
|
||||
* @param checkPrevious only check for overflowing times (after midnight) or don't check for it
|
||||
* @return true if the feature is open
|
||||
*/
|
||||
public boolean isOpenedForTime(Calendar cal, boolean checkPrevious);
|
||||
|
||||
/**
|
||||
* Check if the previous day before "cal" is part of this rule
|
||||
* @param cal; the time to check
|
||||
* @return true if the previous day is part of the rule
|
||||
*/
|
||||
public boolean containsPreviousDay(Calendar cal);
|
||||
|
||||
/**
|
||||
* Check if the day of "cal" is part of this rule
|
||||
* @param cal; the time to check
|
||||
* @return true if the day is part of the rule
|
||||
*/
|
||||
public boolean containsDay(Calendar cal);
|
||||
|
||||
public String toRuleString();
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation of the basic OpeningHoursRule
|
||||
*
|
||||
* This implementation only supports day of weeks and numeral times, or the value "off"
|
||||
*
|
||||
*/
|
||||
public static class BasicDayOpeningHourRule implements OpeningHoursRule {
|
||||
/**
|
||||
* represents the list on which days it is open.
|
||||
* Day number 0 is ???? TODO
|
||||
*/
|
||||
private boolean[] days = new boolean[7];
|
||||
private int startTime = -1;
|
||||
private int endTime = -1;
|
||||
/**
|
||||
* lists of equal size representing the start and end times
|
||||
*/
|
||||
private int[] startTimes, endTimes;
|
||||
|
||||
/**
|
||||
* return an array representing the days of the rule
|
||||
* @return the days of the rule
|
||||
*/
|
||||
public boolean[] getDays() {
|
||||
return days;
|
||||
}
|
||||
|
||||
public void setStartEndTime(int startTime, int endTime) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
@Deprecated
|
||||
/**
|
||||
* set a single start time, erase all previously added start times
|
||||
* @param s startTime to set
|
||||
*/
|
||||
public void setStartTime(int s) {
|
||||
startTimes = new int[]{s};
|
||||
if(endTimes.length != 1) {
|
||||
endTimes = new int[]{0};
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* set a single end time, erase all previously added end times
|
||||
* @param e endTime to set
|
||||
*/
|
||||
public void setEndTime(int e) {
|
||||
endTimes = new int[]{e};
|
||||
if(startTimes.length != 1) {
|
||||
startTimes = new int[]{0};
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* get a single start time
|
||||
* @return a single start time
|
||||
*/
|
||||
public int getStartTime() {
|
||||
return startTime;
|
||||
try {
|
||||
return startTimes[0];
|
||||
} catch (Exception e){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* get a single end time
|
||||
* @return a single end time
|
||||
*/
|
||||
public int getEndTime() {
|
||||
return endTime;
|
||||
try {
|
||||
return endTimes[0];
|
||||
} catch (Exception e){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check if the weekday of time "cal" is part of this rule
|
||||
* @param cal the time to check
|
||||
* @return true if this day is part of the rule
|
||||
*/
|
||||
public boolean containsDay(Calendar cal){
|
||||
int i = cal.get(Calendar.DAY_OF_WEEK);
|
||||
int d = (i + 5) % 7;
|
||||
if (days[d]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check if the previous weekday of time "cal" is part of this rule
|
||||
* @param cal the time to check
|
||||
* @return true if the previous day is part of the rule
|
||||
*/
|
||||
public boolean containsPreviousDay(Calendar cal){
|
||||
int i = cal.get(Calendar.DAY_OF_WEEK);
|
||||
int p = (i + 4) % 7;
|
||||
if (days[p]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpenedForTime(Calendar cal) {
|
||||
if (startTime == -1) {
|
||||
/**
|
||||
* Check if this rule says the feature is open at time "cal"
|
||||
* @param cal the time to check
|
||||
* @return true if this rule contains the day to check and the start and end times denote it's open
|
||||
* @return true if this rule contains the previous day and an endTime>startTime such that the time to check falls before the endtime
|
||||
* @return false in all other cases, also if only day is wrong
|
||||
*/
|
||||
public boolean isOpenedForTime(Calendar cal, boolean checkPrevious) {
|
||||
if (startTimes == null) {
|
||||
return false;
|
||||
}
|
||||
int i = cal.get(Calendar.DAY_OF_WEEK);
|
||||
|
@ -52,26 +279,29 @@ public class OpeningHoursParser {
|
|||
p += 7;
|
||||
}
|
||||
int time = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE);
|
||||
int startTime = this.startTime;
|
||||
int endTime = this.endTime;
|
||||
// one day working 10 - 20 (not 20 - 04)
|
||||
if (startTime < endTime || endTime == -1) {
|
||||
if (days[d]) {
|
||||
if (time >= startTime && (endTime == -1 || time <= endTime)) {
|
||||
for (i = 0; i<startTimes.length; i++){
|
||||
int startTime = this.startTimes[i];
|
||||
int endTime = this.endTimes[i];
|
||||
// one day working 10 - 20 (not 20 - 04)
|
||||
if (startTime < endTime || endTime == -1) {
|
||||
if (days[d] && !checkPrevious) {
|
||||
if (time >= startTime && (endTime == -1 || time <= endTime)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (time >= startTime && days[p] && checkPrevious) {
|
||||
// check in previous day
|
||||
return true;
|
||||
} else if (time <= endTime && days[d] && !checkPrevious) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (time >= startTime && days[p]) {
|
||||
// check in previous day
|
||||
return true;
|
||||
} else if (time <= endTime && days[d]) {
|
||||
// check in previous day
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toRuleString() {
|
||||
StringBuilder b = new StringBuilder(25);
|
||||
|
@ -98,18 +328,27 @@ public class OpeningHoursParser {
|
|||
open24_7 = false;
|
||||
}
|
||||
}
|
||||
if (open24_7 && startTime == 0 && endTime / 60 == 24) {
|
||||
return "24/7";
|
||||
if (startTimes == null || startTimes.length == 0){
|
||||
b.append(" off ");
|
||||
} else {
|
||||
for (int i = 0; i<startTimes.length; i++) {
|
||||
int startTime = startTimes[i];
|
||||
int endTime = endTimes[i];
|
||||
if (open24_7 && startTime == 0 && endTime / 60 == 24) {
|
||||
return "24/7";
|
||||
}
|
||||
b.append(" "); //$NON-NLS-1$
|
||||
int stHour = startTime / 60;
|
||||
int stTime = startTime - stHour * 60;
|
||||
int enHour = endTime / 60;
|
||||
int enTime = endTime - enHour * 60;
|
||||
formatTime(stHour, stTime, b);
|
||||
b.append("-"); //$NON-NLS-1$
|
||||
formatTime(enHour, enTime, b);
|
||||
b.append(",");
|
||||
}
|
||||
}
|
||||
b.append(" "); //$NON-NLS-1$
|
||||
int stHour = startTime / 60;
|
||||
int stTime = startTime - stHour * 60;
|
||||
int enHour = endTime / 60;
|
||||
int enTime = endTime - enHour * 60;
|
||||
formatTime(stHour, stTime, b);
|
||||
b.append("-"); //$NON-NLS-1$
|
||||
formatTime(enHour, enTime, b);
|
||||
return b.toString();
|
||||
return b.substring(0, b.length()-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,17 +356,45 @@ public class OpeningHoursParser {
|
|||
return toRuleString();
|
||||
}
|
||||
|
||||
public void setStartTime(int startTime) {
|
||||
this.startTime = startTime;
|
||||
/**
|
||||
* Add a time range (startTime-endTime) to this rule
|
||||
* @param startTime startTime to add
|
||||
* @param endTime endTime to add
|
||||
*/
|
||||
public void addTimeRange(int startTime, int endTime) {
|
||||
if (startTimes == null){
|
||||
startTimes = new int[] {startTime};
|
||||
endTimes = new int[] {endTime};
|
||||
} else {
|
||||
int l = startTimes.length;
|
||||
int[] newStartTimes = new int[l+1];
|
||||
int[] newEndTimes = new int[l+1];
|
||||
for (int i=0; i<l; i++){
|
||||
newStartTimes[i] = startTimes[i];
|
||||
newEndTimes[i] = endTimes[i];
|
||||
}
|
||||
newStartTimes[l] = startTime;
|
||||
newEndTimes[l] = endTime;
|
||||
|
||||
startTimes = newStartTimes;
|
||||
endTimes = newEndTimes;
|
||||
}
|
||||
}
|
||||
|
||||
public void setEndTime(int endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static OpeningHoursRule parseRule(String r, List<OpeningHoursRule> rs){
|
||||
/**
|
||||
* Parse an opening_hours string from OSM to an OpeningHours object which can be used to check
|
||||
* @param r the string to parse
|
||||
* @param rs the resulting object representing the opening hours of the feature
|
||||
* @return true if the String is successfully parsed
|
||||
*/
|
||||
public static boolean parseRule(String r, OpeningHours rs){
|
||||
// replace words "sunrise" and "sunset" by real hours
|
||||
r = r.replaceAll("sunset", sunset);
|
||||
r = r.replaceAll("sunrise", sunrise);
|
||||
// replace the '+' by an arbitrary value
|
||||
r = r.replaceAll("\\+", "-" + endOfDay);
|
||||
int startDay = -1;
|
||||
int previousDay = -1;
|
||||
int k = 0;
|
||||
|
@ -136,9 +403,9 @@ public class OpeningHoursParser {
|
|||
boolean[] days = basic.getDays();
|
||||
if("24/7".equals(r)){
|
||||
Arrays.fill(days, true);
|
||||
basic.setStartEndTime(0, 24*60);
|
||||
rs.add(basic);
|
||||
return basic;
|
||||
basic.addTimeRange(0, 24*60);
|
||||
rs.addRule(basic);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (; k < r.length(); k++) {
|
||||
|
@ -147,13 +414,17 @@ public class OpeningHoursParser {
|
|||
// time starts
|
||||
break;
|
||||
}
|
||||
if (ch == 'o' && r.charAt(k+1) == 'f' && r.charAt(k+1) == 'f'){
|
||||
// value "off" is found
|
||||
break;
|
||||
}
|
||||
if(Character.isWhitespace(ch) || ch == ','){
|
||||
continue;
|
||||
} else if(ch == '-'){
|
||||
if(previousDay != -1){
|
||||
startDay = previousDay;
|
||||
} else {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
} else if(k < r.length() - 1){
|
||||
int i = 0;
|
||||
|
@ -168,6 +439,14 @@ public class OpeningHoursParser {
|
|||
for (int j = startDay; j <= i; j++) {
|
||||
days[j] = true;
|
||||
}
|
||||
if(startDay > i){// overflow handling, e.g. Su-We
|
||||
for (int j = startDay; j <= 6; j++) {
|
||||
days[j] = true;
|
||||
}
|
||||
for (int j = 0; j <= i; j++){
|
||||
days[j] = true;
|
||||
}
|
||||
}
|
||||
startDay = -1;
|
||||
} else {
|
||||
days[i] = true;
|
||||
|
@ -175,11 +454,14 @@ public class OpeningHoursParser {
|
|||
previousDay = i;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(previousDay == -1){
|
||||
return null;
|
||||
// no days given => take all days.
|
||||
for (int i = 0; i<7; i++){
|
||||
days[i] = true;
|
||||
}
|
||||
}
|
||||
String timeSubstr = r.substring(k);
|
||||
String[] times = timeSubstr.split(",");
|
||||
|
@ -189,6 +471,14 @@ public class OpeningHoursParser {
|
|||
if(time.length() == 0){
|
||||
continue;
|
||||
}
|
||||
if(time.equals("off")){
|
||||
break; // add no time values
|
||||
}
|
||||
if(time.equals("24/7")){
|
||||
// for some reason, this is used. See tagwatch.
|
||||
basic.addTimeRange(0, 24*60);
|
||||
break;
|
||||
}
|
||||
String[] stEnd = time.split("-"); //$NON-NLS-1$
|
||||
if (stEnd.length != 2) {
|
||||
continue;
|
||||
|
@ -199,61 +489,62 @@ public class OpeningHoursParser {
|
|||
try {
|
||||
int i1 = stEnd[0].indexOf(':');
|
||||
int i2 = stEnd[1].indexOf(':');
|
||||
if (i1 == -1 || i2 == -1) {
|
||||
return null;
|
||||
int startHour, startMin, endHour, endMin;
|
||||
if(i1 == -1) {
|
||||
// if no minutes are given, try complete value as hour
|
||||
startHour = Integer.parseInt(stEnd[0].trim());
|
||||
startMin = 0;
|
||||
} else {
|
||||
startHour = Integer.parseInt(stEnd[0].substring(0, i1).trim());
|
||||
startMin = Integer.parseInt(stEnd[0].substring(i1 + 1).trim());
|
||||
}
|
||||
st = Integer.parseInt(stEnd[0].substring(0, i1).trim()) * 60 + Integer.parseInt(stEnd[0].substring(i1 + 1).trim());
|
||||
end = Integer.parseInt(stEnd[1].substring(0, i2).trim()) * 60 + Integer.parseInt(stEnd[1].substring(i2 + 1).trim());
|
||||
if(i2 == -1) {
|
||||
// if no minutes are given, try complete value as hour
|
||||
endHour = Integer.parseInt(stEnd[1].trim());
|
||||
endMin = 0;
|
||||
} else {
|
||||
endHour = Integer.parseInt(stEnd[1].substring(0, i2).trim());
|
||||
endMin = Integer.parseInt(stEnd[1].substring(i2 + 1).trim());
|
||||
}
|
||||
st = startHour * 60 + startMin;
|
||||
end = endHour * 60 + endMin;
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
basic.setStartEndTime(st, end);
|
||||
rs.add(basic);
|
||||
BasicDayOpeningHourRule nbasic = new BasicDayOpeningHourRule();
|
||||
nbasic.days = basic.days;
|
||||
basic = nbasic;
|
||||
basic.addTimeRange(st, end);
|
||||
}
|
||||
rs.addRule(basic);
|
||||
if(!timesExist){
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
return basic;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static List<OpeningHoursRule> parseOpenedHours(String format){
|
||||
/**
|
||||
* parse OSM opening_hours string to an OpeningHours object
|
||||
* @param format the string to parse
|
||||
* @return the OpeningHours object when parsing was successful
|
||||
* @return null when parsing was unsuccessful
|
||||
*/
|
||||
public static OpeningHours parseOpenedHours(String format){
|
||||
// split the OSM string in multiple rules
|
||||
String[] rules = format.split(";"); //$NON-NLS-1$
|
||||
List<OpeningHoursRule> rs = new ArrayList<OpeningHoursRule>();
|
||||
OpeningHours rs = new OpeningHours();
|
||||
for(String r : rules){
|
||||
r = r.trim();
|
||||
if(r.length() == 0){
|
||||
continue;
|
||||
}
|
||||
// check if valid
|
||||
OpeningHoursRule rule = parseRule(r, rs);
|
||||
if(rule == null){
|
||||
boolean rule = parseRule(r, rs);
|
||||
if(!rule){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
public static String toStringOpenedHours(List<? extends OpeningHoursRule> rules){
|
||||
StringBuilder b = new StringBuilder(100);
|
||||
// check 24/7
|
||||
boolean first = true;
|
||||
for (OpeningHoursRule p : rules) {
|
||||
if(p == null){
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
b.append("; "); //$NON-NLS-1$
|
||||
}
|
||||
b.append(p.toRuleString());
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
||||
private static void formatTime(int h, int t, StringBuilder b){
|
||||
if(h < 10){
|
||||
b.append("0"); //$NON-NLS-1$
|
||||
|
@ -265,39 +556,57 @@ public class OpeningHoursParser {
|
|||
b.append(t);
|
||||
}
|
||||
|
||||
private static void testOpened(String time, List<OpeningHoursRule> hours, boolean expected) throws ParseException {
|
||||
boolean opened = false;
|
||||
|
||||
private static void testOpened(String time, OpeningHours hours, boolean expected) throws ParseException {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new SimpleDateFormat("dd.MM.yyyy hh:mm").parse(time));
|
||||
for(OpeningHoursRule r : hours) {
|
||||
if(r.isOpenedForTime(cal)){
|
||||
opened = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("Expected " + expected +" = " + opened);
|
||||
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm").parse(time));
|
||||
System.out.println("Expected " + time+": " + expected +" = " + hours.isOpenedForTime(cal));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ParseException {
|
||||
|
||||
List<OpeningHoursRule> hours = parseOpenedHours("Mo-Fr 08:30-14:40; Sa 08:00 - 14:00"); //$NON-NLS-1$
|
||||
|
||||
//Test basic case
|
||||
OpeningHours hours = parseOpenedHours("Mo-Fr 08:30-14:40" ); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
System.out.println(toStringOpenedHours(hours));
|
||||
hours = parseOpenedHours("Mo-Fr 08:30-14:40,15:00-19:00"); //$NON-NLS-1$
|
||||
testOpened("20.04.2012 14:00", hours, true);
|
||||
testOpened("20.04.2012 15:00", hours, true);
|
||||
testOpened("20.04.2012 14:50", hours, false);
|
||||
testOpened("09.08.2012 11:00", hours, true);
|
||||
testOpened("09.08.2012 16:00", hours, false);
|
||||
// two time and date ranges
|
||||
hours = parseOpenedHours("Mo-We, Fr 08:30-14:40,15:00-19:00"); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
System.out.println(toStringOpenedHours(hours));
|
||||
hours = parseOpenedHours("Mo, We-Fr, Th, Sa 08:30-14:40; Sa 08:00 - 14:00"); //$NON-NLS-1$
|
||||
testOpened("08.08.2012 14:00", hours, true);
|
||||
testOpened("10.08.2012 15:00", hours, true);
|
||||
testOpened("08.08.2012 14:50", hours, false);
|
||||
// test exception on general schema
|
||||
hours = parseOpenedHours("Mo-Sa 08:30-14:40; Tu 08:00 - 14:00"); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
System.out.println(toStringOpenedHours(hours));
|
||||
hours = parseOpenedHours("Mo-Su 00:00-24:00"); //$NON-NLS-1$
|
||||
testOpened("07.08.2012 14:20", hours, false);
|
||||
// test off value
|
||||
hours = parseOpenedHours("Mo-Sa 09:00-18:25; Th off"); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
System.out.println(toStringOpenedHours(hours));
|
||||
testOpened("08.08.2012 12:00", hours, true);
|
||||
testOpened("09.08.2012 12:00", hours, false);
|
||||
//test 24/7
|
||||
hours = parseOpenedHours("24/7"); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
System.out.println(toStringOpenedHours(hours));
|
||||
testOpened("08.08.2012 23:59", hours, true);
|
||||
// some people seem to use the following syntax:
|
||||
hours = parseOpenedHours("Sa-Su 24/7");
|
||||
System.out.println(hours);
|
||||
hours = parseOpenedHours("Mo-Fr 9-19");
|
||||
System.out.println(hours);
|
||||
hours = parseOpenedHours("09:00-17:00");
|
||||
System.out.println(hours);
|
||||
hours = parseOpenedHours("sunrise-sunset");
|
||||
System.out.println(hours);
|
||||
hours = parseOpenedHours("10:00+");
|
||||
System.out.println(hours);
|
||||
hours = parseOpenedHours("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise");
|
||||
System.out.println(hours);
|
||||
testOpened("12.08.2012 04:00", hours, true);
|
||||
testOpened("12.08.2012 23:00", hours, true);
|
||||
testOpened("08.08.2012 12:00", hours, false);
|
||||
testOpened("08.08.2012 05:00", hours, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ public class AHSupermarketResolver {
|
|||
newTags.put("addr:postcode", props.get("zip")+"");
|
||||
|
||||
JSONArray o = (JSONArray) props.get("hours");
|
||||
List<OpeningHoursParser.OpeningHoursRule> rules = new ArrayList<OpeningHoursRule>();
|
||||
OpeningHoursParser.OpeningHours rules = new OpeningHoursParser.OpeningHours();
|
||||
BasicDayOpeningHourRule prev = null;
|
||||
for(int i=0; i<7; i++){
|
||||
JSONObject obj = o.getJSONObject(i);
|
||||
|
@ -207,14 +207,14 @@ public class AHSupermarketResolver {
|
|||
} else {
|
||||
BasicDayOpeningHourRule rule = new OpeningHoursParser.BasicDayOpeningHourRule();
|
||||
rule.getDays()[i] = true;
|
||||
rule.setStartEndTime(start, end);
|
||||
rule.addTimeRange(start, end);
|
||||
prev = rule;
|
||||
rules.add(rule);
|
||||
rules.addRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
newTags.put("opening_hours", OpeningHoursParser.toStringOpenedHours(rules));
|
||||
newTags.put("opening_hours", rules.toString());
|
||||
|
||||
// Check distance to info
|
||||
LatLon real = new LatLon((Double)props.get("lat"), (Double) props.get("lng"));
|
||||
|
|
|
@ -4,24 +4,79 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<LinearLayout android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:orientation="vertical">
|
||||
android:layout_height="wrap_content" android:orientation="vertical">
|
||||
<TextView android:text="@string/create_poi_link_to_osm_doc" android:id="@+id/LinkToOsmDoc" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
|
||||
<TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="1">
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView android:text="@string/poi_dialog_name" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||
<!-- bug with width set it to 100 -->
|
||||
|
||||
<EditText android:text="" android:id="@+id/Name" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width ="100dp"></EditText>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<Button android:text="<Type>" android:id="@+id/TypeButton" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||
|
||||
<Button android:text="<Type>" android:id="@+id/TypeButton" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width ="fill_parent"/>
|
||||
<!-- <EditText android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width = "fill_parent" /> -->
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<Button android:text="@string/poi_dialog_opening_hours" android:id="@+id/OpenHoursButton" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||
|
||||
<EditText android:text="" android:hint="Mo-Su 08:00-20:00" android:id="@+id/OpeningHours" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width ="100dp" android:layout_height="wrap_content"></EditText>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/TextView01"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:text="@string/phone" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Phone"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:hint="0123456789"
|
||||
android:inputType="phone" >
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/TextView02"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:text="@string/website" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Website"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:hint="http://osmand.net" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<TextView android:text="@string/poi_dialog_comment" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||
<EditText android:text="@string/poi_dialog_comment_default" android:id="@+id/Comment" android:layout_marginLeft="5dp" android:layout_width ="100dp" android:layout_marginRight="5dp" android:layout_height="wrap_content"></EditText>
|
||||
|
|
|
@ -1122,4 +1122,5 @@ You can enable (online or cached) tile map sources, tracking settings, and many
|
|||
<string name="edit_filter_delete_message">Filter {0} has been deleted</string>
|
||||
<string name="edit_filter_create_message">Filter {0} has been created</string>
|
||||
<string name="default_buttons_selectall">Select All</string>
|
||||
</resources>
|
||||
|
||||
<string name="email">email</string></resources>
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.osmand.data.Amenity;
|
|||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.OpeningHoursParser;
|
||||
import net.osmand.osm.OpeningHoursParser.OpeningHours;
|
||||
import net.osmand.osm.OpeningHoursParser.OpeningHoursRule;
|
||||
import net.osmand.plus.NameFinderPoiFilter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -727,17 +728,12 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent
|
|||
label.setText(str);
|
||||
int opened = -1;
|
||||
if (amenity.getOpeningHours() != null) {
|
||||
List<OpeningHoursRule> rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
|
||||
OpeningHours rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
|
||||
if (rs != null) {
|
||||
Calendar inst = Calendar.getInstance();
|
||||
inst.setTimeInMillis(System.currentTimeMillis());
|
||||
boolean work = false;
|
||||
for (OpeningHoursRule p : rs) {
|
||||
if (p.isOpenedForTime(inst)) {
|
||||
work = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
work = rs.isOpenedForTime(inst);
|
||||
if (work) {
|
||||
opened = 0;
|
||||
} else {
|
||||
|
|
|
@ -17,6 +17,7 @@ import net.osmand.osm.Node;
|
|||
import net.osmand.osm.OSMSettings.OSMTagKey;
|
||||
import net.osmand.osm.OpeningHoursParser;
|
||||
import net.osmand.osm.OpeningHoursParser.BasicDayOpeningHourRule;
|
||||
import net.osmand.osm.OpeningHoursParser.OpeningHours;
|
||||
import net.osmand.osm.OpeningHoursParser.OpeningHoursRule;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
|
@ -55,6 +56,8 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
private Button openHoursButton;
|
||||
private EditText openingHours;
|
||||
private EditText commentText;
|
||||
private EditText websiteText;
|
||||
private EditText phoneText;
|
||||
|
||||
// private final static Log log = LogUtil.getLog(EditingPOIActivity.class);
|
||||
|
||||
|
@ -155,6 +158,10 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
nameText.setText(a.getName());
|
||||
EditText openingHours = ((EditText)dlg.findViewById(R.id.OpeningHours));
|
||||
openingHours.setText(a.getOpeningHours());
|
||||
EditText phoneText = ((EditText)dlg.findViewById(R.id.Phone));
|
||||
phoneText.setText(a.getPhone());
|
||||
EditText websiteText = ((EditText)dlg.findViewById(R.id.Website));
|
||||
websiteText.setText(a.getSite());
|
||||
updateType(a);
|
||||
}
|
||||
|
||||
|
@ -169,6 +176,9 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
typeText = ((AutoCompleteTextView)dlg.findViewById(R.id.Type));
|
||||
typeText.setThreshold(1);
|
||||
commentText = ((EditText)dlg.findViewById(R.id.Comment));
|
||||
phoneText = ((EditText)dlg.findViewById(R.id.Phone));
|
||||
websiteText = ((EditText)dlg.findViewById(R.id.Website));
|
||||
|
||||
|
||||
TextView linkToOsmDoc = (TextView) dlg.findViewById(R.id.LinkToOsmDoc);
|
||||
linkToOsmDoc.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -279,6 +289,14 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
} else {
|
||||
n.putTag(OSMTagKey.OPENING_HOURS.getValue(), openingHours.getText().toString());
|
||||
}
|
||||
String website = websiteText.getText().toString();
|
||||
if (website.length() > 0 ){
|
||||
n.putTag(OSMTagKey.WEBSITE.getValue(),website);
|
||||
}
|
||||
String phone = phoneText.getText().toString();
|
||||
if (phone.length() > 0 ){
|
||||
n.putTag(OSMTagKey.PHONE.getValue(),phone);
|
||||
}
|
||||
commitNode(action, n, openstreetmapUtil.getEntityInfo(), commentText.getText().toString(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -323,7 +341,7 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
|
||||
|
||||
private Dialog createOpenHoursDlg(){
|
||||
List<OpeningHoursRule> time = OpeningHoursParser.parseOpenedHours(openingHours.getText().toString());
|
||||
OpeningHours time = OpeningHoursParser.parseOpenedHours(openingHours.getText().toString());
|
||||
if(time == null){
|
||||
AccessibleToast.makeText(ctx, ctx.getString(R.string.opening_hours_not_supported), Toast.LENGTH_LONG).show();
|
||||
return null;
|
||||
|
@ -332,7 +350,7 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
List<BasicDayOpeningHourRule> simple = null;
|
||||
if(time != null){
|
||||
simple = new ArrayList<BasicDayOpeningHourRule>();
|
||||
for(OpeningHoursRule r : time){
|
||||
for(OpeningHoursRule r : time.getRules()){
|
||||
if(r instanceof BasicDayOpeningHourRule){
|
||||
simple.add((BasicDayOpeningHourRule) r);
|
||||
} else {
|
||||
|
@ -348,7 +366,8 @@ public class EditingPOIActivity implements DialogProvider {
|
|||
builder.setPositiveButton(ctx.getString(R.string.default_buttons_apply), new DialogInterface.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
openingHours.setText(OpeningHoursParser.toStringOpenedHours(v.getTime()));
|
||||
OpeningHours oh = new OpeningHours((ArrayList<OpeningHoursRule>) v.getTime());
|
||||
openingHours.setText(oh.toString());
|
||||
ctx.removeDialog(DIALOG_OPENING_HOURS);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue