Skip to content

Commit

Permalink
Implemented conditional parsing if duration larger than 2 days, graph…
Browse files Browse the repository at this point in the history
  • Loading branch information
boldtrn committed Feb 16, 2016
1 parent 46df771 commit d85f0fa
Show file tree
Hide file tree
Showing 18 changed files with 1,163 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Licensed to GraphHopper and Peter Karich under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.reader.osm;

import com.graphhopper.reader.OSMWay;
import com.graphhopper.reader.osm.conditional.ConditionalParser;
import com.graphhopper.reader.osm.conditional.DateRange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;
import java.util.List;
import java.util.Set;

/**
* Inspects the conditional tags of an OSMWay according to the given conditional tags.
* <p>
* @author Robin Boldt
*/
public class ConditionalTagsInspector
{

private static final Logger logger = LoggerFactory.getLogger(ConditionalTagsInspector.class);

private final Calendar calendar;
private final List<String> tagsToCheck;
private final ConditionalParser restrictiveParser;
private final ConditionalParser permitParser;
private final boolean enabledLogs = false;

/**
* Create with todays date
*/
public ConditionalTagsInspector( List<String> tagsToCheck, Set<String> restrictiveValues, Set<String> permittedValues )
{
this(Calendar.getInstance(), tagsToCheck, restrictiveValues, permittedValues);
}

/**
* Create with given date
*/
public ConditionalTagsInspector( Calendar date, List<String> tagsToCheck, Set<String> restrictiveValues, Set<String> permittedValues )
{
this.calendar = date;
this.tagsToCheck = tagsToCheck;
this.restrictiveParser = new ConditionalParser(restrictiveValues, enabledLogs);
this.permitParser = new ConditionalParser(permittedValues, enabledLogs);
}

public boolean isRestrictedWayConditionallyPermitted( OSMWay way )
{
return applies(way, true);
}

public boolean isPermittedWayConditionallyRestricted( OSMWay way )
{
return applies(way, false);
}

protected boolean applies( OSMWay way, boolean checkPermissiveValues )
{
for (String tagToCheck : tagsToCheck)
{
tagToCheck = tagToCheck + ":conditional";
String val = way.getTag(tagToCheck);
if (val != null && !val.isEmpty())
{
try
{
DateRange dateRange;
if (checkPermissiveValues)
dateRange = permitParser.getDateRange(val);
else
dateRange = restrictiveParser.getDateRange(val);

if (dateRange != null && dateRange.isInRange(calendar))
return true;
} catch (Exception e)
{
if (enabledLogs)
logger.warn("Could not parse the conditional value:" + val + " of tag:" + tagToCheck + ". Exception:" + e.getMessage());
}
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Licensed to GraphHopper and Peter Karich under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.reader.osm.conditional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.Set;

/**
* Parses a conditional tag according to
* http://wiki.openstreetmap.org/wiki/Conditional_restrictions.
* <p>
* @author Robin Boldt
*/
public class ConditionalParser
{

private final Set<String> restrictedTags;
private static final Logger logger = LoggerFactory.getLogger(ConditionalParser.class);
private final boolean enabledLogs;

public ConditionalParser( Set<String> restrictedTags )
{
this(restrictedTags, false);
}

public ConditionalParser( Set<String> restrictedTags, boolean enabledLogs )
{
this.restrictedTags = restrictedTags;
this.enabledLogs = enabledLogs;
}

public DateRange getDateRange( String conditionalTag ) throws ParseException
{

if (conditionalTag == null || conditionalTag.isEmpty() || !conditionalTag.contains("@"))
return null;

if (conditionalTag.contains(";"))
{
// TODO #374
if (enabledLogs)
logger.warn("We do not support multiple conditions yet: " + conditionalTag);
return null;
}

String[] conditionalArr = conditionalTag.split("@");

if (conditionalArr.length != 2)
throw new IllegalStateException("could not split this condition: " + conditionalTag);

String restrictiveValue = conditionalArr[0].trim();
if (!restrictedTags.contains(restrictiveValue))
return null;

String conditional = conditionalArr[1];
conditional = conditional.replace('(', ' ');
conditional = conditional.replace(')', ' ');
conditional = conditional.trim();

return DateRangeParser.parseDateRange(conditional);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.graphhopper.reader.osm.conditional;

import java.util.Calendar;

/**
* This class represents a date range and is able to determine if a given date is in that range.
*
* @author Robin Boldt
*/
public class DateRange
{
private Calendar from;
private Calendar to;

// Do not compare years
boolean yearless = false;

boolean dayOnly = false;

boolean reverse = false;

// TODO Gets to complex? Create Factory?
public DateRange( ParsedCalendar from, ParsedCalendar to )
{
Calendar fromCal = from.parsedCalendar;
Calendar toCal = to.parsedCalendar;

// This should never happen
if (fromCal.get(Calendar.ERA) != fromCal.get(Calendar.ERA))
{
throw new IllegalArgumentException("Different ERAs are not allowed. From:" + from + " To:" + to);
}

if (from.isYearless() && to.isYearless())
{
yearless = true;
}

if (from.isDayOnly() && to.isDayOnly())
{
dayOnly = true;
}

if (fromCal.after(toCal))
{
if (!yearless && !dayOnly)
{
throw new IllegalArgumentException("From after to makes no sense, except for isYearless and isDayOnly DateRanges. From:" + from + " To:" + to);
} else
{
reverse = true;
}
}

this.from = from.getMin();
this.to = to.getMax();

}

public boolean isInRange( Calendar date )
{
if (!yearless && !dayOnly)
return date.after(from) && date.before(to);

if(dayOnly){
if(reverse){
return (from.get(Calendar.DAY_OF_WEEK) <= date.get(Calendar.DAY_OF_WEEK) || date.get(Calendar.DAY_OF_WEEK) <= to.get(Calendar.DAY_OF_WEEK));
}else{
return (from.get(Calendar.DAY_OF_WEEK) <= date.get(Calendar.DAY_OF_WEEK) && date.get(Calendar.DAY_OF_WEEK) <= to.get(Calendar.DAY_OF_WEEK));
}
}

if (reverse)
return isInRangeYearlessReverse(date);
else
return isInRangeYearless(date);
}

private boolean isInRangeYearless( Calendar date )
{
if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) && date.get(Calendar.MONTH) < to.get(Calendar.MONTH))
return true;
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH) && date.get(Calendar.DAY_OF_MONTH) <= to.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (date.get(Calendar.DAY_OF_MONTH) <= to.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
return false;
}

private boolean isInRangeYearlessReverse( Calendar date )
{
if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) || date.get(Calendar.MONTH) < to.get(Calendar.MONTH))
return true;
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (from.get(Calendar.DAY_OF_MONTH) < date.get(Calendar.DAY_OF_MONTH) || date.get(Calendar.DAY_OF_MONTH) < to.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
{
if (date.get(Calendar.DAY_OF_MONTH) >= to.get(Calendar.DAY_OF_MONTH))
return true;
else
return false;
}
return false;
}


}
Loading

0 comments on commit d85f0fa

Please sign in to comment.