New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Landuse buffer #2812
base: landuse
Are you sure you want to change the base?
Landuse buffer #2812
Conversation
@@ -23,7 +23,7 @@ | |||
public enum Landuse { | |||
OTHER("other"), FARMLAND("farmland"), RESIDENTIAL("residential"), | |||
GRASS("grass"), FOREST("forest"), MEADOW("meadow"), ORCHARD("orchard"), FARMYARD("farmyard"), | |||
INDUSTRIAL("industrial"), VINEYARD("vineyard"), CEMETRY("cemetry"), COMMERCIAL("commercial"), ALLOTMENTS("allotments"), | |||
INDUSTRIAL("industrial"), VINEYARD("vineyard"), CEMETERY("cemetery"), COMMERCIAL("commercial"), ALLOTMENTS("allotments"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! I fixed this directly in the main branch
// todonow: do we really need the prepared geometry for osm areas? | ||
IndexedCustomArea<T> indexedCustomArea = new IndexedCustomArea<>(area, pgf.create(border)); | ||
index.insert(border.getEnvelopeInternal(), indexedCustomArea); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try anything in this direction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I didn't. I'm also not sure what you mean by that comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't want to delete your comment. I restored it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I tried this in the meantime. The SRTRee only allows querying for rectangular shapes, so use it for the envelopes of the areas. But once we query the index and get the envelopes we need a more precise intersection check and this would be too slow if we did not create a prepared geometry for each area (I tested this and it was about 10x slower). So we need to prepare the geometries beforehand, even though it does not really matter what we put into the SRTree
I think I agree we should do something along this line, but did you try it and check the results? How does it affect the quality of the landuse encoded value and the performance of the import? Did you look for some examples where the landuse association is improved and maybe some where this leads to problems? Also I'm not sure if we should change it here, because it would affect the other usages of the area index as well. |
So far I tested with the display feature of the graph in my home area only. From what I could see the problematic cases all work as they should.
OK, then we need another method. |
…into landuse-buffer # Conflicts: # core/src/main/java/com/graphhopper/routing/ev/Landuse.java
I ran a benchmark with the austria latest OSM file and compared your implementation against mine: I was able to reduce So my version is unfortunately significantly slower 😞 . Anyway, I still think that it is an improvement which is worth the increased time. Do you have an idea how this can be optimised? |
@ratrun You could also use @easbar i fear that these calculations might over- or underflow near the lat/lon extrema. There are no bound checks or logic to shift something like graphhopper/core/src/main/java/com/graphhopper/util/DistanceCalcEarth.java Lines 105 to 117 in 948294f
|
It might also be worth to apply the |
new Coordinate(lon+rLon,lat-rLat), | ||
new Coordinate(lon-rLon,lat-rLat) | ||
}; | ||
Polygon poly = gf.createPolygon(coordinates); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Polygon poly = gf.createPolygon(coordinates); | |
Polygon poly = (Polygon) gf.toGeometry(searchEnv); |
But then we would have to create a prepared rectangle for every query (=for every edge), don't we?. As we only do a few (often only one) lookup for each rectangle preparation this could be even slower? Or maybe I did not understand what you mean? Also right now we first select the 'center' point for each edge and then use it as the center of a rectangle we query with. I'd rather use the entire edge and draw a buffer around it. And actually I'd rather buffer the landuse polygons, and then query with the edge, because we can easily parallelize the landuse buffering. I'm working on this currently.
I'm also not sure if we need this, since we use the JTS calculations on the unprojected coordinates anyway. Of course this is not accurate, but then we can just as well skip these calculations. And like I said I do not see much value in first converting an edge into a single point and then extending it to become a rectangle.
Good idea, but when I tried this unfortunately the queries did not become much faster while running the simplification took a significant amount of time. |
Thanks for all the feedback! In f4ba483 I implemented the usage of the BBox and generate the polygon from the searchEnv. The result of a new benchmark was |
If I understood it correctly I gave this a try in commit a4d34e4. The result of my benchmark was
I`m courious about this outcome here. I currently do not believe that such an approach could be faster, but we'll see. |
Good point. Buffering the landuse polygons is the best way to scale this. |
Can we take a step back and think about what we want to use landuse for? @ratrun which of the landuse values do you think are even relevant for routing? According to taginfo the most relevant values are: farmland 21.92% Do you have some real examples in OSM where using the landuse tag improves the routes? |
IMHO, the most important use case would be the identification of built-up areas. Essentially a data-driven approach to improving the classification results obtained from #2637 {
"speed": [
{
"if": "development == RESIDENTIAL || landuse == RESIDENTIAL",
"limit_to": "50"
}
]
}
|
Yes, that is what I think as well. The thing I don't know is if the |
I would think so, yes. The heuristic approach is based on the density of the graph. A linear settlement with no driveways might be enough to cause a false-negative. |
I would like to use
Maybe we can use the example from this blogpost for the |
If a route avoids residential landuse, wouldn't it be considered greenery? |
Basically yes. But I expect problems with
|
I would combine them to be honest. Residential is a bit misleading because the classification should rather be called "built-up" which includes residential, industrial, etc |
Why is |
} | ||
|
||
public List<T> query(double lat, double lon) { | ||
Envelope searchEnv = new Envelope(lon, lon, lat, lat); | ||
BBox bbox = dc.createBBox(lon, lat, 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be lat, lon, 10
not lon, lat, 10
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for detecting this bug! I ran a new benchmark with the corrected order of the parameters and got following result: [main] INFO org.eclipse.jetty.server.Server - Started @596397ms
, which is just a bit slower.
That should work fairly well using urban_density |
Yes, this is a case where urban_density might fail to identify a settlement. The landuse=residential tag fixes this if it encircles the whole settlement as it is often done for small villages. |
According to the wiki it is to be used for small areas. From what I have seen so far it is also used most often in urban areas. There people seem to map every small green spot. |
You are probably right. But with the landuse encoded value it would also be possible to prefer |
Ok so besides urban_density we would only need |
I think that this would be sufficient, but other people might have other needs. |
That would be an argument for me to ignore it. |
Here I implemented a 10 meters search buffer and fixed a typo.