Hi Calvin,

 

Thanks for sending me this from the Developers list. I am not a part of the 
Developer list, so I did not see the Join attribute by location tip from Andrea.

 

Anyway, what do you mean with not getting fast result with single point lookups?

When I select a single point from the 10000 point layer and run the same 
algorithm (check the selected features only option in the dialogue box), the 
result takes 0.05 seconds (12 seconds for all 10000). At least that is what is 
says in the log tab of the algorithm. And it sure looks quick.

 

Jeroen

 

 

Van: C Hamilton <[email protected]> 
Verzonden: dinsdag 9 februari 2021 16:25
Aan: Nyall Dawson <[email protected]>
CC: Andrea Giudiceandrea <[email protected]>; qgis-developer 
<[email protected]>; Groene Bij <[email protected]>
Onderwerp: Re: [QGIS-Developer] timzonefinder vs point in polygon

 

Nyall,

 

Using "Join attributes by location" on a large set of points is fast, but if 
you are doing single point lookups it bothers me that I am not getting that 
fast of results in comparison to timezonefinder. The 10,000 points is intended 
to test the speed of many single point lookups. If I were going to actually do 
10,000 point lookups I would use the Join attributes by location, but here are 
my results of single point lookups using timezonefinder vs. your method. Note 
that the assumption is that they can be anywhere in the EPSG:4326 bounding box. 
I am not trying to constrain them to the QGIS canvas.

 

timezonefinder: 44 seconds

Your method: 144 seconds

 

Here is my code for each:

 

timezonefinder

from timezonefinder import TimezoneFinder
import time
tf = TimezoneFinder()

l = iface.activeLayer()
features = l.getFeatures()

start_time = time.time()
for f in features:
    pt = f.geometry().asPoint()
    name = tf.certain_timezone_at(lng=pt.x(), lat=pt.y())
print('Time {}'.format(time.time() - start_time))

 

Your method:

import time
tzlayer = QgsVectorLayer("W:\\My 
Documents\\GitHub\\timezone_speed_lookup_test\\timezones.gpkg", "timezones", 
"ogr")

l = iface.activeLayer()
features = l.getFeatures()

start_time = time.time()
for f in features:
    pt = f.geometry().asPoint()
    rect = QgsRectangle( pt.x()-0.0000000001, pt.y()-0.000000001, pt.x(),pt.y())
    request = QgsFeatureRequest().setFilterRect(rect)
    zones_intersecting_bounding_box = tzlayer.getFeatures(request)
    for tz_feature in zones_intersecting_bounding_box:
        if tz_feature.geometry().intersects(rect):
            name = tz_feature[1]
            break

print('Time {}'.format(time.time() - start_time))

 

 

I'd suggest using similar logic to what join attributes by location
does internally. In pseudocode:

search_point = ...
search_bbox = QgsRectangle( search_point.x() - some tolerance,
search_point.y() - some_tolerance, ... )
request = QgsFeatureRequest().setFilterRect(search_bbox)
zones_intersecting_bounding_box = tz_layer.getFeatures(request)
for time_zone_feature in zones_intersecting_bounding_box:
    if time_zone_feature.intersects(search_point):
        # found a hit!
        break

This will take advantage of whatever spatial index you have on the
time zone layer (e.g. the internal shapefile/gpkg/... index)

There's quite a number of extra optimisations which could be done here
if the speed isn't sufficient for mouse movements, e.g. you could
fetch all the zone features in the canvas extent and "prepare" their
geometries for ultra fast point in polygon tests, and then invalidate
this cache and rebuild on each canvas extent change. But I'd only do
that kind of thing if needed...

Nyall





>
> Calvin
>
> On Fri, Feb 5, 2021 at 6:30 PM Nyall Dawson <[email protected] 
> <mailto:[email protected]> > wrote:
>>
>> On Sat, 6 Feb 2021 at 07:54, Andrea Giudiceandrea <[email protected] 
>> <mailto:[email protected]> > wrote:
>> >
>> > C Hamilton wrote
>> > > Using the algorithm Vector->Geoprocessing Tools->Intersection: 4 minutes,
>> > > 4
>> > > seconds
>> >
>> > Hi Calvin,
>> > maybe it could be better to use the "Join attributes by location" 
>> > algorithm.
>> > It only takes few seconds to preform the join.
>>
>> Confirmed - for me it only takes ~2 seconds, and that's on an
>> non-optimised debug build! There may be a few % more performance boost
>> on the proper QGIS release builds.
>>
>> "Join attributes by location" has a bunch of extra logic to optimise
>> the method that the join is performed, which really pays off in this
>> particular situation (matching points to polygons, where number of
>> points >> number of polygons).
>>
>> Nyall
>>
>>
>>
>> >
>> > Regards.
>> >
>> > Andrea
>> >
>> >
>> >
>> > --
>> > Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Developer-f4099106.html
>> > _______________________________________________
>> > QGIS-Developer mailing list
>> > [email protected] <mailto:[email protected]> 
>> > List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>> > Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>> _______________________________________________
>> QGIS-Developer mailing list
>> [email protected] <mailto:[email protected]> 
>> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

_______________________________________________
Qgis-user mailing list
[email protected]
List info: https://lists.osgeo.org/mailman/listinfo/qgis-user
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-user

Reply via email to