23

I'm looking for a library in javascript that would allow me to make geospatial queries. I know about OpenLayers and GoogleMaps, but this two do not support things like union intersection and so on.

+----+
|    |
|  +-+--+
+--+-+  |
   |    |
   +----+

to

    +----+
    |    |
    |    +--+
    +--+    |
       |    |
       +----+
wolktm
  • 263
  • 3
  • 10

8 Answers8

6

Update 2014-04-29: Check out Turf, looks really promising

JSTS can do unions of geometric objects in the browser. JSTS integrates with the openlayers library and it extends openlayers geometric classes (e.g. OpenLayers.Geometry.Polygon) so they are capable of geometric operations. Example:

>> var poly1 = OpenLayers.Geometry.Polygon.createRegularPolygon(
                                   new OpenLayers.Geometry.Point(0.0,0.0), 2, 5);
>> var poly2 = OpenLayers.Geometry.Polygon.createRegularPolygon(
                                   new OpenLayers.Geometry.Point(1.0,1.0), 2, 4);
>> var poly_u = poly1.union(poly2);
>> var poly_d = poly1.difference(poly2);
>> print(poly_u);
POLYGON((1.5667154718422638 -0.4142135623730949,1.1755705045849463 -1.618033988749895,
  -1.1755705045849465 -1.6180339887498947,-1.902113032590307 0.618033988749895,
  -0.41421356237309503 1.6990562312593451,-0.4142135623730949 2.414213562373095,
   2.414213562373095 2.414213562373095,2.414213562373095 -0.4142135623730949,
   1.5667154718422638 -0.4142135623730949))

Geoscript JS is nice if you want to do serverside geometric operations in JS.

ivy
  • 5,539
  • 1
  • 34
  • 48
  • Geoscript Was already proposed here but I think it is server-side only. JSTS looks like the solutionI was looking for! – wolktm Sep 16 '11 at 07:10
  • Ah, I thought geoscript-js --> is javascript --> must be a browser library. But I can't find how to run it in a browser, so you must be right. jsts it is :) – ivy Sep 16 '11 at 08:57
3

I wrote Spatial Query https://github.com/netshade/spatial_query to do just this.

Alternatively, you could check out http://geoscript.org/index.html , which is likely better supported than Spatial Query is. If you decide to check out SQ though, I'd be flattered to hear if it worked for you.

Chris Zelenak
  • 2,158
  • 17
  • 20
  • As a matter of fact I use spatial_query right now I like it but it has some bugs in union :( Talking about geoscript, it looks like some sort of a serverside code, is it able to run in browser? – wolktm Feb 16 '11 at 08:35
  • If you can post an example of the input data that's screwing up ( here or in GH issues for Spatial Query ) I will see what I can do to fix the implementation. – Chris Zelenak Feb 16 '11 at 14:36
  • AFA geoscript, you're right, my apologies - I didn't look further into the package requirements. Might be able to be ported, but I can't be certain of this atm - sorry for the inaccuracy. – Chris Zelenak Feb 16 '11 at 14:40
1

You can extend OpenLayers to support this operation. I make this using OpenLayers native functions. Try this, maybe you must fix and customize this code.

// The first object is instanced using data given from gmaps
var objBound1 = new OpenLayers.Bounds();
objBound1.extend(new OpenLayers.LonLat(2,2));
objBound1.extend(new OpenLayers.LonLat(8,8));

// The second object is instanced using data given from gmaps
var objBound2 = new OpenLayers.Bounds();
objBound2.extend(new OpenLayers.LonLat(5,5));
objBound2.extend(new OpenLayers.LonLat(10,10));

// Extract limits from our objects
var arrBound1 = objBound1.toArray();
var arrBound2 = objBound2.toArray();

// Determine an virtual bound. It must contain our two bounds
var intMinLeft = arrBound1.left < arrBound2.left ? arrBound1.left : arrBound2.left;
var intMinTop = arrBound1.top < arrBound2.top ? arrBound1.top : arrBound2.top;
var intMaxRight = arrBound1.right > arrBound2.right ? arrBound1.right : arrBound2.right;
var intMaxBottom = arrBound1.bottom > arrBound2.bottom ? arrBound1.bottom : arrBound2.bottom;

// Search all points of virtual bound, storing the points contained in bound1 or bound2
var objBoundResult = new OpenLayers.Bounds();
for(var intI = intMinLeft; intI < intMaxRight; intI++) {
    for(var intJ = intMinTop; intJ < intMaxBottom; intJ++) {
        if(objBound1.containsLonLat(new OpenLayers.LonLat(intI, intJ)) || objBound2.containsLonLat(new OpenLayers.LonLat(intI, intJ))) {
            objBoundResult.add(intI, intJ);
        }
    }
}

// objBoundResult is what you want
0

You can get query results for a radius or rectangle that includes your polygon, then filter the results using the technique described here: http://msdn.microsoft.com/en-us/library/cc451895.aspx. The example uses bing maps, but you could easily use the same principles using whatever mapping service you prefer.

gilly3
  • 87,962
  • 25
  • 144
  • 176
  • Intersections are addressed also in stock OpenLayers, but Union is not addressed in article. – wolktm Jan 23 '11 at 12:23
0

Did you look at geoUtils?

I am not sure whether it supports the union op, but might be worth giving a try.

Art
  • 23,747
  • 29
  • 89
  • 101
-1

If you have a server available, you can run the ESRI ArcGIS Server 10 and start a Geometry service. This has this functionality available through an API (including REST) interface. Look at their help documentation: SOAP SDK

Ruz
  • 246
  • 1
  • 3
-1

You cound use the PostGIS DB wich has support for JDBC. Check here for an example: http://postgis.refractions.net/docs/ch05.html#id2644717

:)

DsP

ramrunner
  • 161
  • 1
  • 6
-1

Do you really need to do this on the client side? Union is a fairly heavy operation and might be better done on the server side.

Another API that may be useful is the ArcGIS Javascript API, although from what I can see I don't think it will do union without ArcGIS Server: http://help.arcgis.com/en/webapi/javascript/arcgis/

Gnat
  • 2,861
  • 1
  • 21
  • 30
  • 1
    ArcGIS - Serverside and paid - no thx ;) Servside is slow () and I have to do union of just 2 polygons so javascript performance is not a problem (at least in webkit) – wolktm Feb 16 '11 at 08:20
  • What service are you querying? If the service is limiting you by accepting a single polygon, then doing union on the client side like you say is probably the only option you've got. Otherwise, if you're doing queries to your own server then why not do it on the server side? If it's only two polygons, then you could also do the query twice and aggregate the results. – Gnat Feb 16 '11 at 13:52