I need to use IBM Informix for my project where I have point coordinates and I need to find which points are present in query rectangular region.
Informix has spatial datablade module with ST_POINT and ST_POLYGON data objects.
I know how to create, insert and create r-tree index on tables with such objects.
But problem is how to do a SELECT statement, something which list all the points in a particular rectangular region.
You've got the Spatial Datablade documentation at your fingertips? It is available in the IDS 11.50 Info Centre.
For example, the section in Chapter 1 discusses performing spatial queries:
Performing Spatial Queries
A common task in a GIS application is to retrieve the visible subset of spatial data for display in a window. The easiest way to do this is to define a polygon representing the boundary of the window and then use the SE_EnvelopesIntersect() function to find all spatial objects that overlap this window:
SELECT name, type, zone FROM sensitive_areas
WHERE SE_EnvelopesIntersect(zone,
ST_PolyFromText('polygon((20000 20000,60000 20000,60000 60000,20000 60000,20000 20000))', 5));
Queries can also use spatial columns in the SQL WHERE clause to qualify the result set; the spatial column need not be in the result set at all. For example, the following SQL statement retrieves each sensitive area with its nearby hazardous waste site if the sensitive area is within five miles of a hazardous site. The ST_Buffer() function generates a circular polygon representing the five-mile radius around each hazardous location. The ST_Polygon geometry returned by the ST_Buffer() function becomes the argument of the ST_Overlaps() function, which returns t (TRUE) if the zone ST_Polygon of the sensitive_areas table overlaps the ST_Polygon generated by the ST_Buffer() function:
SELECT sa.name sensitive_area, hs.name hazardous_site
FROM sensitive_areas sa, hazardous_sites hs
WHERE ST_Overlaps(sa.zone, ST_Buffer(hs.location, 26400));
sensitive_area Summerhill Elementary School
hazardous_site Landmark Industrial
sensitive_area Johnson County Hospital
hazardous_site Landmark Industrial
Related
I have a graph G with n nodes. The graph is embedded in 2D space (so that there are well-defined angles and distances between each pair of nodes). Some nodes might be connected with edges to other nodes. Given a location L, this graph needs to be laid out on top of a map close to L, such that each node becomes a marker on a map, and such that there is a walkable path between each pair of connected of nodes. Since this will not be possible most of the time, I will allow the graph to be scaled/rotated and I will alow the distances and angles between nodes to be flexible within a certain range.
In order for me to write this specific algorithm, I would need to have some specific information about the streets near L. Does anybody know to get street data as a graph structure (so that I can get walkable paths)? I know the Google Maps API allows you to get directions between two points but I'm sure I cannot just keep getting directions without incurring any cost.
Edit: I've been reading a bit about OpenStreetMap API. It looks like this could be interesting. Maybe people can comment on this as well.
You can also check out these sites for osm and open gis data.
OpenStreetMap Extracts, here
OpenStreetMap derived data, here
GIS Datasets, here
in addition to these;
Planet.osm/diffs here
i hope it helps you...
The TIGER datasets offer a shape/line file for the USA, free. Lots of options including roads. https://www.census.gov/geo/maps-data/data/tiger-line.html
I am calculating the skyline of a set of points where each point has a number of dimensions where each dimension has a double value. My input can be anything from thousands to millions of points with multiple dimensions. I am creating an algorithm where I have a huge map created as an RDD. The RDD looks like this:
JavaPairRDD<Tuple2<Integer, Integer>, BitSet> map
Where the first int is the dimension, the second the ranking of a double in that dimension and BitSet is a bit representation of that value in that dimension. This map is smaller than the input but still can be very large (usually 10000+ elements) elements and I need to distribute it between all nodes. The first thing I did was a broadcast:
Broadcast<Map<Tuple2<Integer, Integer>, BitSet>> broadcasted = sparkContext.broadcast(map.collectAsMap());
Which of course fails in Big Data because this map is way too memory consuming. This map needs to be accessed by every node in a read-only mode in order to perform some calculations, for example a node will do (with the broadcast):
BitSet bitSet = (BitSet) broadcasted.value().get(key).clone()
// perform calculations
This action will be done during a map or a filter action so I can't keep the map as an RDD and do lookup. Specifically, the second RDD that needs to access the map RDD looks like this:
JavaPairRDD<Point, Iterable<Tuple2<Integer, Integer>> values;
where the Iterable<Tuple2<Integer, Integer>> is the list of keys that the Point needs during a 'filter' in order for me to see if the point is in the skyline or not.
JavaRDD<Point2D> skylines = pointsWithKeys
.filter(p -> isSkyline(p._2()))
.map(Tuple2::_1);
Inside isSkyline I need access to the map in order to access the bitsets depending on the keys I give it.
What is a more efficient way to distribute it between the nodes?
I'm facing the following task in ArcGIS - I'm using ArcMap 10.2
I have a polygon shapefile with counties of (say) a state in US. From this shapefile, I create a layer which marks all counties in which there is at least 1 city of more than 50000 inhabitants (I think of this as the treatment condition). Then I'm creating buffers around the polygons in my layer of counties with those large cities, i.e. I'm drawing a buffer of say 100km around every county that has at least one city with more than 50000 inhabitants.
So far so good!
The final step of this exercise should be to create a count for every polygon with the number of buffers that are touching this polygon. For instance, the buffers around counties B, C and D all touch county A. However county A doesn't have a city of more than 50000 inhabitants. Hence, I want the count for city A to be 3 (it's touched by B, C and D). I created the union of all my buffers but I simply can't find the right way to create this count for every polygon.
I've done an extensive Google search and I'm apologize if I overlooked the obvious solution.
Any help is appreciated!
Michael Kaiser
[Staff Research Assistant UCSD]
If I understand what you want correctly, then creating the union of buffers won't help you - as it leaves you with a single object and you need the count of all buffered objects intersecting against every object in the original table.
In SQL I would join the original (all counties) layer to your new (filtered, buffered) layer using the STIntersects() method. Something like the following:
DECLARE #original TABLE
(
[Original_Id] INT NOT NULL,
[Original_Geom] GEOGRAPHY NOT NULL
);
DECLARE #filtered TABLE
(
[Buffered_Id] INT NOT NULL,
[Buffered_Geom] GEOGRAPHY NOT NULL
);
-- We'll pretend the above tables are filled with data
SELECT
ORIGINAL.[Original_Id],
COUNT(FILTERED.[Filtered_Id]) AS [NumberOfIntersections]
FROM
#original AS ORIGINAL
JOIN
#filtered AS FILTERED ON (ORIGINAL.[Original_Geom].STIntersects(FILTERED.[Filtered_Geom] = 1)
GROUP BY
ORIGINAL.[Original_Id]
Explanation:
In this example, the #original table would contain all of your counties in your given state - as they were before you buffered them. [Original_Id] would contain something that you can relate to or use to relate back to your data and [Original_Geometry] would contain the county's boundary.
The #filtered table would contain a subset of #original - in your case only those with at least 1 city of 50,000 inhabitants. The [Buffered_Id] would match records in [Original_Id] (as an example Orange County may have Id 32) and [Buffered_Geometry] would contain the county's boundary, buffered by (as in your example) 100km.
Using my example exactly, you need to get the required data out of your tables and in to mine, but you should be able to use your tables and adjust as necessary to reference them.
NOTE: If you do not wish "Orange County" to count "Orange County (Buffered)" in the above query, you will need to add a WHERE clause to filter them out.
I haven't the data to hand to test this, but it should be mostly there. Hope it helps.
i'm trying to develop a web service able to give me back the name of the administrative area that contains a given gps position.
I have already developed a java application able to insert some polygons (administrative areas of my country) in neo4j using spatial plugin and Java API. Then, giving a gps position, i'm able to get the name of the polygon that contains it.
Now i'm trying to do the same using REST API of Neo4j (instead of java api) but i'm not able to find any example.
So my questions are:
1) Is possible to insert polygons in Neo4j using REST API (if i well understood is possible using WKT format) ?
2) is possible to execute a spatial query that finds all polygons that contain a given gps position ?
thanks, Enrico
The answer to both of your questions is yes. Here are example steps that use REST and Cypher.
1) Create your spatial layer and index (REST). In this example, my index is named 'test' (a layer of the same name and base spatial nodes will be created), and the name of the property on my nodes that will contain the wkt geometry information is 'wkt'.
POST http://localhost:7474/db/data/index/node {"name":"test", "config":{"provider":"spatial", "wkt":"wkt"}}
2) Create a node (Cypher). You can have labels and various properties. The only part that Neo4j Spatial cares about is the 'wkt' property. (You could do this step with REST.)
CREATE (n { name : "Fooville", wkt : "POLYGON((11.0 11.0, 11.0 12.0, 12.0 12.0, 12.0 11.0, 11.0 11.0))" })
3) Add the node to the layer. You can do this by adding the node to the index or to the layer, but there is an important difference. If you add it to the index, a copy node containing only the geometry data will be created, and that will be added to the layer. Querying via Cypher will return your original node, but querying via REST or Java will return the copy node. If you add the node directly to the layer, then you must take an extra step if you want to be able to query with Cypher later. In both cases you will need the URI of the node, the last element of which is the Neo4j node number. In the example below, I assume the node number is 4 (which it will be if you do this example on a fresh, empty database).
Method 1:
POST http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addNodeToLayer { "layer":"test", "node":"http://localhost:7474/db/data/node/4" }
To make this node searchable via Cypher, add the node number to the node as a user 'id' property. (You could do this with REST.)
START n = node(4) SET n.id = id(n)
Method 2: Using this method will double your node count, double your WKT storage, and produce differing results when querying via REST vs Cypher.
POST http://localhost:7474/db/data/index/node/test {"value":"dummy","key":"dummy","uri":"http://localhost:7474/db/data/node/4"}
3) Run your query. You can do a query in REST or Cypher (assuming you conditioned the nodes as described above). The Cypher queries available are: 'withinDistance', 'withinWKTGeometry', and 'bbox'. The REST queries available are: 'findGeometriesWithinDistance', 'findClosestGeometries', and 'findGeometriesInBBox'. It's interesting to note that only Cypher allows you to query for nodes within a WKT geometry. There's also a difference in REST between the findClosestGeometries and findGeometriesWithinDistance that I don't yet understand, even though the arguments are the same. To see how to make the REST calls, you can issue these commands:
POST http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance
POST http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findClosestGeometries
POST http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesInBBox
The Cypher queries are: (replace text between '<>', including the '<>', with actual values)
START n = node:<layer>("withinDistance:[<y>, <x>, <max distance in km>]")
START n = node:<layer>("withinWKTGeometry:POLYGON((<x1> <y1>, ..., <xN> <yN>, <x1> <y1>))")
START n = node:<layer>("bbox:[<min x>, <max x>, <min y>, <max y>]")
I have assumed in all of this that you are using a longitude/latitude coordinate reference system (CRS), so x is longitude and y is latitude. (This preserves a right-handed coordinate system in which z is up.)
My question is almost similar to this. But in my case, the polygons are not necessarily touching/overlapping each other. They are present all over the space.
I have a big set of such polygons. Similarly, I have a huge set of points. I am currently running a RoR module that takes 1 point at a time and checks the intersection with respect to 1 polygon at a time. The database is PostGIS. The performance is quite slow.
Is there a faster or optimal way of doing this?
Can be done as one select statement, but for performance....look into a gist index on your polygons. FOr simplicity, lets say I have a table with a polygon field (geom data type) and a point field (geom data type). If you are doing a list of points in a list of polygons, do a cross join so each polygon and each point is compared.
select *
from t1 inner join t2 on 1=1
where st_contains(t1.poly,t2.point) = 't'
(modified to include the table join example. I'm using a cross join, which means every polygon will be joined to every point and compared. If we're talking a large record set, get those GIS tree indexes going)
I'm currently doing this to locate a few million points within a few hundred polygons. If you have overlapping polygons, this will return multiple rows for every point thats located in 2 or more polygons.
May fail pending on the data type your points are stored as. If they are in a geom field, it'll flow fine. If you are using text values, you'll need to use the st.geomfromtext statement to turn your characters into a point. This will look more like:
st_contains(poly, st_geomfromtext('POINT('||lon||' ' ||lat ||')')) = 't'
I used a lat/lon example...only thing to watch for here is the geomfromtext requires you to create the point using || to create the string from your field. Let me know if you need assistance with the st_geomfromtext concept.