1

I have a shapefile that represents all the Hydrological Basins in the world. You can download the file from here:

http://www.fao.org/geonetwork/srv/en/resources.get?id=38047&fname=Major_hydrological_basins.zip&access=private

In that file, there's the whole world divided into areas (all the Hydrological Basins in the world). I need to create a function that query the shapefile with latitude and longitude, and gets back the values of that point, that are: MAJ_BAS, MAJ_NAME and MAJ_AREA

I need to do this server side, without a GUI. To me seems simple, when I do in my QGIS I just click on a point and get back the informations I need, so I thought "there'll be a function that you'll give latitude and longitude, and the function will answer with the datas of that point". But I've been looking for 2 days and still get no solution about this problem.

I'm quite new to QGIS.

1
  • You could set up a WMS or WFS server and use either WMS GetFeatureInfo request like demo.mapserver.org/cgi-bin/… (note that it is not really meant to be used without GUI) or WFS GetFeature with some suitable filter. With basins which are area "Intersects" filter should be fine. Read first more about WMS and WFS and come back then.
    – user30184
    Aug 3, 2015 at 22:01

2 Answers 2

1

If you are using PyQGIS then I think you can use the QGSVectorLayer.select() method to select objects in a given search rectangle.

See @nathan-w example code here which seems a good starting point: How do I allow users to select features with the mouse?

layer.select( layer.pendingAllAttributesList(), rect, True, True)    
for feature in layer:
0
1

And thanks for your precious answers! I see your methods are much more rigorous than what I found out yesterday night, working on my project, and I appreciate all your answers.

Since I need just a few queries, what I did was to create a table in MySQL with polygon objects and then use the algorythim of point in polygon. I created a function in MySQL that's the follwing

DETERMINISTIC
BEGIN 
DECLARE n INT DEFAULT 0; 
DECLARE pX DECIMAL(9,6); 
DECLARE pY DECIMAL(9,6); 
DECLARE ls LINESTRING; 
DECLARE poly1 POINT; 
DECLARE poly1X DECIMAL(9,6); 
DECLARE poly1Y DECIMAL(9,6); 
DECLARE poly2 POINT; 
DECLARE poly2X DECIMAL(9,6); 
DECLARE poly2Y DECIMAL(9,6); 
DECLARE i INT DEFAULT 0; 
DECLARE result INT(1) DEFAULT 0; 
SET pX = X(p); 
SET pY = Y(p); 
SET ls = ExteriorRing(poly); 
SET poly2 = EndPoint(ls); 
SET poly2X = X(poly2); 
SET poly2Y = Y(poly2); 
SET n = NumPoints(ls); 
WHILE i<n DO 
SET poly1 = PointN(ls, (i+1)); 
SET poly1X = X(poly1); 
SET poly1Y = Y(poly1); 
IF ( ( ( ( poly1X <= pX ) && ( pX < poly2X ) ) || ( ( poly2X <= pX ) && ( pX < poly1X ) ) ) && ( pY > ( poly2Y - poly1Y ) * ( pX - poly1X ) / ( poly2X - poly1X ) + poly1Y ) ) THEN 
SET result = !result; 
END IF; 
SET poly2X = poly1X; 
SET poly2Y = poly1Y; 
SET i = i + 1; 
END WHILE; 
RETURN result; 
End

If the function returns 1, the point is in the polygon. If it returns 0, it's not.

Then, when I need to find if a point is inside a polygon, I'll just query like this

select * from *Polygon_table* where myWithin(PointFromText( concat( 'POINT(', *{$long}*, ' ', *{$lat}*, ')' ) ), *Polygon_table*.polygon )

where myWithin is the name of the function and the polygon in the Polygon table has been saved as a Polygon object. This function returns the polygon(s) that contain(s) that point.

I know this is not the fastest solution, but for my case (one single query not often) was a great solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.