We are building an application where I am a driver and i travel from point A to point B.On my way i can find passengers who travel in the same route.
We are using PostgreSQL with PostGIS extension.
After googling a lot i have found out that we can use linestring to achieve this.I am not fully sure whether this approach will work out.
Suppose I have co-ordinates of my source and destination.
var RouteCoordinates = [
{lat: 37.772, lng: -122.214},
{lat: 21.291, lng: -157.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
I need to store this as linestring in my DB.
After stroring if a passenger is also going in this route but as we know his source and destination wont be exactly in my line string but they will be near.
For example around 1km radius
As you can see my source and destination is that line. And as I am travelling I want to pick all those whose (source and destination) are near to my routes (within particular radius)
If I want to find particular location in my DB within particular radius I will be querying like this
SELECT id, name, address, geom
FROM Seattle_Starbucks
WHERE ST_DWithin(geom, ST_MakePoint(-122.325959,47.625138)::geography, 1000);
Now I can achieve my solution as I am new to postGIS its little bit confusing
How to store all all my source and destination point in DB
ANS: I need to convert in to linestring using this function ST_MakeLine and then store, right?
How to query that based on my requirement as I have mentioned above
Can you please give me the insight on how to achieve this. Your help is greatly appreciated. Thanks
A few thougths on your question:
I need to convert in to linestring using this function ST_MakeLine and
then store, right?
Yes, to merge multiple points into a LINESTRING you can use ST_MakeLine:
SELECT ST_AsText(
ST_MakeLine(ARRAY[ST_MakePoint(-122.21,37.77),
ST_MakePoint(-157.82,21.29),
ST_MakePoint(178.43,-18.14),
ST_MakePoint(153.02,-27.46)]));
st_astext
---------------------------------------------------------------------
LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)
(1 Zeile)
How to query that based on my requirement as I have mentioned above
Create a buffer on each point of your LINESTRING and check wether other geometries are inside of it.
First, you have to split your rout LINESTRING into POINTs using ST_DumpPoints ...
db=# SELECT ST_AsText((ST_DumpPoints('LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)'::GEOMETRY)).geom);
st_astext
----------------------
POINT(-122.21 37.77)
POINT(-157.82 21.29)
POINT(178.43 -18.14)
POINT(153.02 -27.46)
(4 Zeilen)
.. and then use ST_Buffer to create a buffer around each point. ST_Buffer returns a geometry with the area surrounding your point (or any other geometry type). For instance, taking the first point of your route (if I didn't switch x and y, it's somewhere in San Francisco) POINT(-122.21 37.76):
db=# SELECT ST_AsText(
ST_Buffer('POINT(-122.21 37.76)'::GEOMETRY,0.0001, 'quad_segs=16'));
Returns this geometry:
POLYGON((-122.2099 37.76,-122.209900481527 37.759990198286,-122.209901921472 37.7599804909678,-122.209904305966 37.7599709715323,-122.209907612047 37.7599617316568,-122.209911807874 37.7599528603263,-122.209916853039 37.7599444429767,-122.209922698955 37.7599365606716,-122.209929289322 37.7599292893219,-122.209936560672 37.7599226989547,-122.209944442977 37.7599168530388,-122.209952860326 37.7599118078736,-122.209961731657 37.7599076120467,-122.209970971532 37.7599043059664,-122.209980490968 37.759901921472,-122.209990198286 37.7599004815273,-122.21 37.7599,-122.210009801714 37.7599004815273,-122.210019509032 37.759901921472,-122.210029028468 37.7599043059664,-122.210038268343 37.7599076120467,-122.210047139674 37.7599118078736,-122.210055557023 37.7599168530388,-122.210063439328 37.7599226989547,-122.210070710678 37.7599292893219,-122.210077301045 37.7599365606716,-122.210083146961 37.7599444429767,-122.210088192126 37.7599528603263,-122.210092387953 37.7599617316568,-122.210095694034 37.7599709715323,-122.210098078528 37.7599804909678,-122.210099518473 37.759990198286,-122.2101 37.76,-122.210099518473 37.760009801714,-122.210098078528 37.7600195090322,-122.210095694034 37.7600290284677,-122.210092387953 37.7600382683432,-122.210088192126 37.7600471396737,-122.210083146961 37.7600555570233,-122.210077301045 37.7600634393284,-122.210070710678 37.7600707106781,-122.210063439328 37.7600773010453,-122.210055557023 37.7600831469612,-122.210047139674 37.7600881921264,-122.210038268343 37.7600923879533,-122.210029028468 37.7600956940336,-122.210019509032 37.760098078528,-122.210009801714 37.7600995184727,-122.21 37.7601,-122.209990198286 37.7600995184727,-122.209980490968 37.760098078528,-122.209970971532 37.7600956940336,-122.209961731657 37.7600923879533,-122.209952860326 37.7600881921264,-122.209944442977 37.7600831469612,-122.209936560672 37.7600773010453,-122.209929289322 37.7600707106781,-122.209922698955 37.7600634393284,-122.209916853039 37.7600555570233,-122.209911807874 37.7600471396737,-122.209907612047 37.7600382683432,-122.209904305966 37.7600290284677,-122.209901921472 37.7600195090322,-122.209900481527 37.760009801714,-122.2099 37.76))
If you're wondering about the shape of this buffer, please read this answer.
And using this query you can check if another geometry is inside of this buffer (ST_Within):
db=# SELECT
ST_Within('POINT(-122.21 37.76)'::GEOMETRY,
ST_Buffer('POINT(-122.21 37.76)'::GEOMETRY,0.0001, 'quad_segs=16'));
st_within
-----------
t
(1 Zeile)
To put it all together, you can use a CTE (aka WITH clause) and write something like this:
WITH j AS (
SELECT
(ST_DumpPoints('LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)'::GEOMETRY)).geom AS g)
SELECT id, name, address, geom
FROM Seattle_Starbucks
WHERE ST_Within(geom,ST_Buffer(j.g,0.0001, 'quad_segs=16'))
a greeting, a friend happened to me a route of transportation and I step in the following format:
0102000020E610000049020000F2D077B7B23A53C0F03504C7651428C07E703E75AC3A53C07E37DDB2431428C07E8AE3C...
He told me it was a MultiLineString. I used the PostGIS function:
SELECT St_asewkt ('0102000020E6100000810200 .....');
with this i supposedly should be able to get the wkt format that I can
get the coordinates and use it on google maps api to paint a path in android, but when using it throws me empty. Help me please
I need to get something like MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4)) ... to get lat lng coordinates to paint it in google maps api with android.
To summarize what I have is this value
0102000020E6100000810200 ..... and would like to paint it in android with google maps api, that's why I try to get the coordinates that function.
What you have is Well know binary, WKB, which is explained on this page along with its companion well known text (WKT), but in an ASCII (hex) representation, see the docs
If you do something like:
select st_setsrid(st_makepoint(50, -2),4326);
you will see 0101000020E6100000000000000000494000000000000000C0, similar to what you have.
You can insert these directly into a db with
create table test (g geometry);
insert into test(g) values(ST_GeomFromEWKB(E'\\x0101000020E6100000000000000000494000000000000000C0')
where the E'\\x indicates that you are inserted a hex string, see binary format docs.
If you now do
select g from test;
you will get your WKB back and if you do
select st_astext(g) from test;
you will see the more human-readable WKT format.
The best way to load data in the correct format is to use:
COPY table_name FROM your_file.csv CSV;
where your wkb would be, as is, unquoted, in the your_file.csv.
On Slackware 14.0 x86_64 with postgresql-9.2.4 and postgis-2.0.3.
Have loaded essex-latest.osm.pbf into a database.
I want to get the centre of the roads in Essex, but am having problems.
These work OK:
SELECT st_Extent(way), st_area(st_Extent(way)) from planet_osm_roads;
st_extent | st_area
------------------------------------------------+------------------
BOX(-10979.62 6693910.54,144349.79 6822695.15) | 20004037488.3802
SELECT center(box '((-10979.62, 6693910.54),(144349.79, 6822695.15))');
center
-------------------------
(66685.085,6758302.845)
(But I have wondered why the function is center and not st_center).
Anyway, so why doesn't this work:
SELECT center(st_Extent(way)) from planet_osm_roads;
ERROR: function center(box2d) does not exist
LINE 1: SELECT center(st_Extent(way)) from planet_osm_roads;
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Cheers,
Peter
Function center gets argument of type box, not box2d that st_Extent returns. With ST_Centroid you doesn't need to call st_Extent even, try ST_Centroid(way)
center is not a PostGIS function, it is a core geometry function for PostgreSQL.
The best way to find the midpoint of a linestring is to use a linear referencing function (e.g., ST_Line_Interpolate_Point() or ST_LineInterpolatePoint() for PostGIS >=2.1).
See also ST_PointOnSurface.
Hi I'm trying to import a shape file from
http://www.nyc.gov/html/dcp/html/bytes/bytesarchive.shtml
into a postgis database. the above files creates MULTIPOLYGONS when i import using shp2pgsql.
then i'm trying to simply determine if lat/long points are contained in my multipolygons
however my select's are not working, and when i print out the poitns of my the_geom column it seems to be very broken.
select st_astext(geom) from (select (st_dumppoints(the_geom)).* from nybb where borocode =1) foo;
gives the result...
st_astext
------------------------------------------
POINT(1007193.83859999 257820.786899999)
POINT(1007209.40620001 257829.435100004)
POINT(1007244.8654 257833.326199993)
POINT(1007283.3496 257839.812399998)
POINT(1007299.3502 257851.488900006)
POINT(1007320.1081 257869.218500003)
POINT(1007356.64669999 257891.055800006)
POINT(1007385.6197 257901.432999998)
POINT(1007421.94509999 257894.084000006)
POINT(1007516.85959999 257890.406100005)
POINT(1007582.59110001 257884.7861)
POINT(1007639.02150001 257877.217199996)
POINT(1007701.29170001 257872.893099993)
...
for points in nyc, this is very off.. what am i doing wrong?
The points are not of. The spatial data that is referred to is NOT in lat/long. This is why numbers are different from what you expect. If you need it to be in long/lat it must be reprojected. See more here: http://postgis.refractions.net/news/20020108/
The projection of the data seems to be in the NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet coordinate system (according to the metadata - see code.).
<spref>
<horizsys>
<planar>
<planci>
<plance Sync="TRUE">coordinate pair</plance>
<coordrep>
<absres Sync="TRUE">0.000000</absres>
<ordres Sync="TRUE">0.000000</ordres>
</coordrep>
<plandu Sync="TRUE">survey feet</plandu>
</planci>
<mapproj><mapprojn Sync="TRUE">Lambert Conformal Conic</mapprojn><lambertc><stdparll Sync="TRUE">40.666667</stdparll><stdparll Sync="TRUE">41.033333</stdparll><longcm Sync="TRUE">-74.000000</longcm><latprjo Sync="TRUE">40.166667</latprjo><feast Sync="TRUE">984250.000000</feast><fnorth Sync="TRUE">0.000000</fnorth></lambertc></mapproj></planar>
<geodetic>
<horizdn Sync="TRUE">North American Datum of 1983</horizdn>
<ellips Sync="TRUE">Geodetic Reference System 80</ellips>
<semiaxis Sync="TRUE">6378137.000000</semiaxis>
<denflat Sync="TRUE">298.257222</denflat>
</geodetic>
<cordsysn>
<geogcsn Sync="TRUE">GCS_North_American_1983</geogcsn>
<projcsn Sync="TRUE">NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet</projcsn>
</cordsysn>
</horizsys>
</spref>
If you work much with spatial data I suggest that you read more about map projection.
I think this is not issue with PostGIS. I checked input esri Shape file nybb.shp with AvisMap Free Viewer and as you see points are weird itself:
However there is something interesting in nybb.shp.xml metadata file:
<spdom>
<bounding>
<westbc Sync="TRUE">-74.257465</westbc>
<eastbc Sync="TRUE">-73.699450</eastbc>
<northbc Sync="TRUE">40.915808</northbc>
<southbc Sync="TRUE">40.495805</southbc>
</bounding>
<lboundng>
<leftbc Sync="TRUE">913090.770096</leftbc>
<rightbc Sync="TRUE">1067317.219904</rightbc>
<bottombc Sync="TRUE">120053.526313</bottombc>
<topbc Sync="TRUE">272932.050103</topbc>
</lboundng>
</spdom>
I am not familiar with those toolkit (ESRI ArcCatalog), but most probably you need to rescale your points after import using that metadata.
I'm importing shapefiles into a Postgres+PostGIS database.
Here's my usual procedure:
* Find an srid in the spatial_ref_sys table where srtext appears to match the shapefile's .prj file
* Upload the data into a new table using the shp2pgsql utility, specifying the srid using the -s flag
* Add the new table to my main geometry table, and on the way convert to an srid of 4269 (the Census standard projection) using ST_Transform
Unfortunately, the spatial_ref_sys table doesn't include Mississippi state's standard projection. The contents of their .prj file is as follows, where I've bolded the parts I usually try to match:
PROJCS["mstm",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",1300000.0],PARAMETER["Central_Meridian",-89.75],PARAMETER["Scale_Factor",0.9998335],PARAMETER["Latitude_Of_Origin",32.5],UNIT["Meter",1.0]]
I eventually found the ogr2ogr utility, and especially with the "peace and joy" promises, I decided to give it a try. I tried this command:
ogr2ogr -update -f "PostgreSQL" PG:"Connection details"
"File name.shp" -t_srs EPSG:4269 -nln Table_Name
I am now getting the error "Terminating translation prematurely after failed translation of layer" -- which seems to indicate that ogr2ogr is not going to be the savior I imagined in getting arbitrary .prj files neatly into the 4269 projection.
Any ideas about what to do?
Here it is on spatialreference.org
http://spatialreference.org/ref/epsg/3814/
You just need to use epsg 3814. I highly reccomend spatialreference.org for finding SRIDs