SQL क्वेरी PostGIS से एक पूर्ण जियोजोन सुविधा है?


35

मैं PostGIS की संपत्तियों के साथ एक जियोजोन सुविधा प्राप्त करना चाहूंगा। मुझे एक सुविधा संग्रह करने के लिए एक उदाहरण मिला है , लेकिन मैं इसे केवल एक सुविधा के लिए काम नहीं कर सकता।

SELECT row_to_json(fc)
 FROM ( SELECT 'FeatureCollection' As type, array_to_json(array_agg(f)) As features
 FROM (SELECT 'Feature' As type
    , ST_AsGeoJSON(lg.geog)::json As geometry
    , row_to_json(lp) As properties
   FROM locations As lg 
         INNER JOIN (SELECT loc_id, loc_name FROM locations) As lp 
       ON lg.loc_id = lp.loc_id  ) As f )  As fc;

अब तक मैंने उदाहरण के फीचर संग्रह क्वेरी को संशोधित करने का प्रयास किया। लेकिन आउटपुट मान्य नहीं है।


मुझे एक और ऐप के लिए कॉन्सेप्ट का प्रूफ देना था इसलिए इस रेपो को एक साथ रखा, जो कि यहाँ से जवाबों का उपयोग करता है। उम्मीद है कि इस सामान के साथ शुरुआत करने में मदद मिलेगी - इसे यहां खोजें: pg-us-census-poc
zak

जवाबों:


59

यह json_build_objectPostgreSQL 9.4+ के साथ थोड़ा और अधिक किया जा सकता है , जो आपको वैकल्पिक कुंजी / मान तर्क की आपूर्ति करके एक JSON का निर्माण करने देता है। उदाहरण के लिए:

SELECT json_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::json,
    'properties', json_build_object(
        'feat_type', feat_type,
        'feat_area', ST_Area(geom)::geography
     )
 )
 FROM input_table;

PostgreSQL 9.5+ में चीजें और भी बेहतर हो जाती हैं, जहां jsonbडेटा टाइप ( डॉक्स ) के लिए कुछ नए ऑपरेटर जोड़े जाते हैं । इससे एक "गुण" ऑब्जेक्ट सेट करना आसान हो जाता है जिसमें सब कुछ होता है लेकिन आईडी और ज्यामिति

SELECT jsonb_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::jsonb,
    'properties', to_jsonb(row) - 'gid' - 'geom'
) FROM (SELECT * FROM input_table) row;

एक FeatureCollection बनाना चाहते हैं? बस इसे सभी के साथ लपेटें jsonb_agg:

SELECT jsonb_build_object(
    'type',     'FeatureCollection',
    'features', jsonb_agg(features.feature)
)
FROM (
  SELECT jsonb_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::jsonb,
    'properties', to_jsonb(inputs) - 'gid' - 'geom'
  ) AS feature
  FROM (SELECT * FROM input_table) inputs) features;

1
अकेले इस कार्यक्षमता में मुझे आज सुबह 9.3.5 से 9.5.3 तक अपग्रेड करने की सुविधा है। यदि केवल यह उतना ही सरल था regexp_replace(current_setting('server_version'),'(\d)\.(\d)\.(\d)','\1.\3.\2')...
जीटी।

1
ठीक है - अब सभी अपग्रेड किए गए हैं (हालांकि विंडोज सेवा के रूप में चलाने के लिए 9.5.3 नहीं मिल सकता है)। किसी भी तरह ... दिए गए उदाहरण के बारे में एक छोटी सी बात - दूसरे json_build_objectमें कॉमा के बजाय कॉलोन हैं।
जी.टी.

मेरे लिए pg v9.6 पर काम नहीं करता है
पाक

2
पूर्णता के लिए, यह संभावना है कि ज्यामिति के सिरों को सख्त जियोजोन (दाएं हाथ के नियम) के लिए सही क्रम में नहीं है, इसे ठीक करने के लिए, हम ST_ForcePolygonCCW / postgis.net/docs/manual-dev/ के
chrismarx

1
@chrismarx यह एक अच्छा बिंदु है और इस मुद्दे को उठाता है कि क्या PostGIS के ST_AsGeoJSONफ़ंक्शन को अपने आप से अभिविन्यास को सही करने के लिए संशोधित किया जाना चाहिए।
dbaston 16

21

इस उत्तर का उपयोग PostgreSQL संस्करण पूर्वकाल 9.4 के साथ किया जा सकता है। PostgreSQL 9.4+ के लिए dbaston के उत्तर का उपयोग करें

क्वेरी निम्न है: (जहाँ 'GEOM'ज्योमेट्री फील्ड है, idजोसन प्रॉपर्टीज में शामिल करने के लिए फ़ील्ड, shapefile_featureटेबल नेम, और 489445फीचर की आईडी चाहता है)

SELECT row_to_json(f) As feature \
     FROM (SELECT 'Feature' As type \
     , ST_AsGeoJSON('GEOM')::json As geometry \
     , row_to_json((SELECT l FROM (SELECT id AS feat_id) As l)) As properties \
     FROM shapefile_feature As l WHERE l.id = 489445) As f;

उत्पादन:

{
   "geometry":{
      "type":"MultiPolygon",
      "coordinates":[
         [
            [
               [
                  -309443.24253826,
                  388111.579584133
               ],
               [
                  -134666.391073443,
                  239616.414560895
               ],
               [
                  -308616.222736376,
                  238788.813082666
               ],
               [
                  -309443.24253826,
                  388111.579584133
               ]
            ]
         ]
      ]
   },
   "type":"Feature",
   "properties":{
      "feat_id":489445
   }
}

चूँकि आपने इसे अपने प्रश्न के शरीर से उत्तर में स्थानांतरित कर दिया है, क्या इसका मतलब यह क्वेरी और परिणाम अब सही ढंग से काम कर रहा है? GeoJSONLint के माध्यम से इसे चलाने पर , यह अभी भी मान्य आउटपुट नहीं देता है।
रयानडाल्टन

1
महान, यह समझ में आता है। मुझे लगता है कि मैं अभी काफी करीब से नहीं देखा था। एक बार GIS.SE इसे प्रश्न को बंद करने की अनुमति देता है, इसे "स्वीकृत" के रूप में चिह्नित करें। धन्यवाद!
रयानडाल्टन

1
यह केवल GeoJSONLint नहीं है जो एकल उद्धरण स्वीकार नहीं करता है। JSON औपचारिक रूप से एकल उद्धरण को या तो नहीं पहचानता है। यदि कोई भी पार्सर उन्हें पहचानता है, तो यह एक अमानवीय विस्तार है और शायद सबसे अच्छा बचा है।
jpmc26

@ बेलो रदर जो जसन dictनहीं है। वे बहुत अलग चीजें हैं। JSON एक स्ट्रिंग है। हमेशा। यह एक पाठ प्रारूप है, उसी तरह XML सिर्फ एक पाठ प्रारूप है। A dictस्मृति ऑब्जेक्ट में है।
jpmc26

5

बस dbaston के उत्तर के लिए एक मामूली सुधार (मैं टिप्पणी करूंगा लेकिन मेरे पास कोई अंक नहीं है) आपको j_son के रूप में ST_AsGeoJSON का आउटपुट देने की आवश्यकता है (चीज़ ::json):

SELECT json_build_object(
  'type',       'Feature',
  'id',         gid,
  'geometry',   ST_AsGeoJSON(geom)::json,
  'properties', json_build_object(
    'feat_type', feat_type,
    'feat_area', ST_Area(geom)::geography
  )
)
FROM input_table;

अन्यथा ज्यामिति सदस्य एक स्ट्रिंग होने जा रहा है। यह वैध नहीं है


4

@ जोबॉन पावेल उर्फ ​​बारका द्वारा @ dbaston के उत्तर को हाल ही में संशोधित किया गया है, और यह मेरे अंत में अवैध जियोजोन पैदा करता है। जैसा कि संशोधित किया गया है, सुविधाओं पर एकत्रीकरण प्रत्येक सुविधा को एक json ऑब्जेक्ट के अंदर नेस्टेड देता है, जो अमान्य है।

मेरे पास सीधे उत्तर पर टिप्पणी करने की प्रतिष्ठा नहीं है, लेकिन अंतिम jsonb_agg कॉलम "फ़ीचर" पर होना चाहिए, न कि "फ़ीचर" सबक्वेरी पर। कॉलम नाम (या "features.feature" पर एकत्र होने पर यदि आप इसे सही पाते हैं) एकत्रीकरण के बाद "एलिमेंट" एरे में प्रत्येक तत्व को सीधे रखता है, जो कि जाने का सही तरीका है।

तो निम्नलिखित, जो @ dbaston के उत्तर के समान है, जैसा कि कुछ सप्ताह पहले तक था (प्लस @ नाम पॉवेल के नामकरण में सुधार) काम करता है:

SELECT jsonb_build_object(
  'type',     'FeatureCollection',
  'features', jsonb_agg(feature)
)
FROM (
  SELECT jsonb_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::jsonb,
    'properties', to_jsonb(inputs) - 'gid' - 'geom'
  ) AS feature
  FROM (
    SELECT * FROM input_table
  ) inputs
) features;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.