পোস্টজিআইএস-এ নিয়মিত বহুভুজ গ্রিড তৈরি করছেন?


61

পোলিগিসে বহুভুজের আকারে, একটি নির্দিষ্ট আকারের বহুভুজ / বর্গক্ষেত্রের একটি নিয়মিত গ্রিড কীভাবে তৈরি করতে হয়?

আমি পোস্টগিসের বহুভুজের অভ্যন্তরে নিয়মিত পয়েন্ট গ্রিড কীভাবে তৈরি করব? কেবল স্কোয়ারের জন্য, যাতে স্কোয়ারগুলি 5m x 5m বা 10m x 10m হতে পারে। তবে এটি সঠিক উপায়ে পরিবর্তন করার কোনও ধারণা নেই।


2
আপনি যে সাধারণীকরণটি খুঁজছেন তা পরিষ্কার নয়। আপনি কি বলছেন যে আপনি একটি (স্বেচ্ছাসেবী) একক বহুভুজ দিয়ে শুরু করেছেন এবং এর একত্রে অনুলিপিগুলি দিয়ে বিমানটি টাইল করতে চান? সাধারণভাবে এটি সম্ভব নয় তবে সম্ভবত এই বহুভুজের নির্দিষ্ট বৈশিষ্ট্য রয়েছে (সম্ভবত এটি একটি সমান্তরাল, ত্রিভুজ বা ষড়ভুজ হিসাবে পরিচিত)।
whuber

উত্তর:


60

এখানে একটি সেট রিটার্নিং ফাংশন ST_CreateFishnetযা বহুভুত জ্যামিতির 2D গ্রিড তৈরি করে:

CREATE OR REPLACE FUNCTION ST_CreateFishnet(
        nrow integer, ncol integer,
        xsize float8, ysize float8,
        x0 float8 DEFAULT 0, y0 float8 DEFAULT 0,
        OUT "row" integer, OUT col integer,
        OUT geom geometry)
    RETURNS SETOF record AS
$$
SELECT i + 1 AS row, j + 1 AS col, ST_Translate(cell, j * $3 + $5, i * $4 + $6) AS geom
FROM generate_series(0, $1 - 1) AS i,
     generate_series(0, $2 - 1) AS j,
(
SELECT ('POLYGON((0 0, 0 '||$4||', '||$3||' '||$4||', '||$3||' 0,0 0))')::geometry AS cell
) AS foo;
$$ LANGUAGE sql IMMUTABLE STRICT;

যেখানে nrowএবং ncolসারি এবং কলামগুলির সংখ্যা xsizeএবং ysizeকক্ষের আকারের দৈর্ঘ্য এবং alচ্ছিক x0এবং y0নীচে-বাম কোণে স্থানাঙ্ক হয়।

নীচের বাম কোণে 1 থেকে শুরু হওয়া ফলাফল rowএবং colসংখ্যাগুলি এবং geomপ্রতিটি ঘরের জন্য আয়তক্ষেত্রাকার বহুভুজ। উদাহরণস্বরূপ:

SELECT *
FROM ST_CreateFishnet(4, 6, 10, 10) AS cells;
 row | col |         geom
-----+-----+--------------------------------
   1 |   1 | 0103000000010000000500000000...
   2 |   1 | 0103000000010000000500000000...
   3 |   1 | 0103000000010000000500000000...
   4 |   1 | 0103000000010000000500000000...
   1 |   2 | 0103000000010000000500000000...
   2 |   2 | 0103000000010000000500000000...
   ...
   3 |   6 | 0103000000010000000500000000...
   4 |   6 | 0103000000010000000500000000...
(24 rows)

বা সম্পূর্ণ গ্রিডের জন্য একটি একক জ্যামিতি সংগ্রহ করতে:

SELECT ST_Collect(cells.geom)
FROM ST_CreateFishnet(4, 6, 10, 10) AS cells;

4x6 গ্রিড

আপনি x0/ y0উত্স অফসেটগুলি যোগ করতে পারেন (এগুলি শূন্যে ডিফল্ট হয়েছে)।


1
ধন্যবাদ! এখন আমাকে কেবল বহুভুজের বিবিক্সের সাথে ফিশনেট বাঁধতে হবে।
mk.archaeo

এটি খুব সহায়ক .. আমার একটি প্রশ্ন আছে। আমি বহুভুজ / বক্সের অভ্যন্তরে গ্রিডগুলি কীভাবে তৈরি করতে পারি?
মোহাম্মদ শফীক

চমৎকার কাজের মাইক, এটি খুব সহায়ক।
মৌনায়েম

56

উত্পাদনের একটি নির্দিষ্ট বৈকল্পিকতা এমন একটি পরিস্থিতির জন্য যখন আপনার একটি স্থির মেট্রিক পদক্ষেপ সহ কোনও ভৌগলিক মানচিত্রের জন্য গ্রিড তৈরি করা প্রয়োজন (কোষগুলি গ্রুপিং মানগুলির জন্য ব্যবহার করা যেতে পারে, যেমন কোনও অঞ্চলে বাজির ঘনত্ব)।

ফাংশনটি খুব মার্জিত নয়, তবে আমি সেই কাজের জন্য এর চেয়ে ভাল কোনও সমাধান খুঁজে পাইনি (উপরে মাইক টিউজের ফাংশন সহ)। সুতরাং আপনার একটি সীমাবদ্ধ বহুভুজ (যেমন গুগল ম্যাপস ইন্টারফেস থেকে আগত), মিটারে একটি ধাপের মান থাকে:

CREATE OR REPLACE FUNCTION public.makegrid_2d (
  bound_polygon public.geometry,
  grid_step integer,
  metric_srid integer = 28408 --metric SRID (this particular is optimal for the Western Russia)
)
RETURNS public.geometry AS
$body$
DECLARE
  BoundM public.geometry; --Bound polygon transformed to the metric projection (with metric_srid SRID)
  Xmin DOUBLE PRECISION;
  Xmax DOUBLE PRECISION;
  Ymax DOUBLE PRECISION;
  X DOUBLE PRECISION;
  Y DOUBLE PRECISION;
  sectors public.geometry[];
  i INTEGER;
BEGIN
  BoundM := ST_Transform($1, $3); --From WGS84 (SRID 4326) to the metric projection, to operate with step in meters
  Xmin := ST_XMin(BoundM);
  Xmax := ST_XMax(BoundM);
  Ymax := ST_YMax(BoundM);

  Y := ST_YMin(BoundM); --current sector's corner coordinate
  i := -1;
  <<yloop>>
  LOOP
    IF (Y > Ymax) THEN  --Better if generating polygons exceeds the bound for one step. You always can crop the result. But if not you may get not quite correct data for outbound polygons (e.g. if you calculate frequency per sector)
        EXIT;
    END IF;

    X := Xmin;
    <<xloop>>
    LOOP
      IF (X > Xmax) THEN
          EXIT;
      END IF;

      i := i + 1;
      sectors[i] := ST_GeomFromText('POLYGON(('||X||' '||Y||', '||(X+$2)||' '||Y||', '||(X+$2)||' '||(Y+$2)||', '||X||' '||(Y+$2)||', '||X||' '||Y||'))', $3);

      X := X + $2;
    END LOOP xloop;
    Y := Y + $2;
  END LOOP yloop;

  RETURN ST_Transform(ST_Collect(sectors), ST_SRID($1));
END;
$body$
LANGUAGE 'plpgsql';

এটি কিভাবে ব্যবহার করতে:

SELECT cell FROM 
(SELECT (
ST_Dump(makegrid_2d(ST_GeomFromText('Polygon((35.099577 45.183417,47.283415 45.183417,47.283415 49.640445,35.099577 49.640445,35.099577 45.183417))',
 4326), -- WGS84 SRID
 10000) -- cell step in meters
)).geom AS cell) AS q_grid

সুতরাং আপনি দেখতে পাচ্ছেন যে উত্পন্ন বহুভুজ দ্বারা ফর্ম্যাট করা রেখাগুলি ভৌগলিক সমান্তরাল এবং মেরিডিয়ানদের পাশে রয়েছে - এটি খুব সুবিধাজনক।

50 কিলোমিটার পদক্ষেপ সহ গ্রিডের উদাহরণ

পরামর্শ: আপনি যদি ঘনত্বের মতো কোনও কিছু গণনা করেন (উদাহরণস্বরূপ কোষগুলির দ্বারা বজ্রপাতের মানচিত্র) এবং গ্রিডটি গতিশীলভাবে উত্পন্ন হয় তবে কার্যকারিতা বাড়াতে আমি কলামটিতে স্থানিক সূচক সহ জ্যামিতি বহুভুজ হিসাবে ঘরগুলি সংরক্ষণের জন্য অস্থায়ী টেবিলগুলি ব্যবহার করার পরামর্শ দেব represents সেল।


আমি আশা করি আমি এটি আবারও ভোট দিতে পারতাম ... এটি একটি নিখুঁত সমাধান ছিল! এবং সমন্বিত সিস্টেমটি কাস্টমাইজ করার ক্ষমতা দুর্দান্ত ~!
DPSSpatial

কেবলমাত্র একটি ছোট্ট পরামর্শ, যুক্ত করার জন্য ST_GeomFromTextএকটি বাক্স তৈরি করার সময় ব্যবহার করার পরিবর্তে sectors, আপনি বাক্সের ST_MakeEnvelopeনীচে বাম এবং উপরে ডান স্থানাঙ্কগুলি ব্যবহার করতে পারেন এবং নির্দিষ্ট করতে পারেন ।
ম্যাট

এটি সম্ভাব্যতা নিয়ে আসে
ডাক্তাররা

11

আপনি একটি খালি রাস্টার ভেক্টরাইজিং করে একটি নিয়মিত গ্রিড তৈরি করতে পারেন:

SELECT (ST_PixelAsPolygons(ST_AddBand(ST_MakeEmptyRaster(100, 100, 1.1, 1.1, 1.0), '8BSI'::text, 1, 0), 1, false)).geom

1
এটি এত সহজ সমাধান, এটি বেশ কয়েকবার ভেক্টর উপায়ে সম্পন্ন করে।
জন পাওয়েল

6

আমি @ আলেকজান্ডারের ফাংশনের একটি বৈকল্পিক তৈরি করেছি যার প্রয়োজন নেই যে আমরা অন্য একটি এসআরআইডিতে রূপান্তর করব। এটি কোনও নির্দিষ্ট অঞ্চলের ইউনিট হিসাবে মিটার ব্যবহার করে এমন একটি অভিক্ষেপ খুঁজে পাওয়ার বিষয়টি এড়িয়ে চলে। এটি ব্যবহার করে ST_Projectসঠিকভাবে দেওয়া অভিক্ষেপ ব্যবহার দীর্ঘ করা। আমি একটি জুড়েছেন width_stepএবং height_stepপরিবর্তে তারা স্কোয়ার হতে প্রয়োজন এর আয়তক্ষেত্রাকার টাইল জন্য অনুমতি দেয়।

CREATE OR REPLACE FUNCTION public.makegrid_2d (
  bound_polygon public.geometry,
  width_step integer,
  height_step integer
)
RETURNS public.geometry AS
$body$
DECLARE
  Xmin DOUBLE PRECISION;
  Xmax DOUBLE PRECISION;
  Ymax DOUBLE PRECISION;
  X DOUBLE PRECISION;
  Y DOUBLE PRECISION;
  NextX DOUBLE PRECISION;
  NextY DOUBLE PRECISION;
  CPoint public.geometry;
  sectors public.geometry[];
  i INTEGER;
  SRID INTEGER;
BEGIN
  Xmin := ST_XMin(bound_polygon);
  Xmax := ST_XMax(bound_polygon);
  Ymax := ST_YMax(bound_polygon);
  SRID := ST_SRID(bound_polygon);

  Y := ST_YMin(bound_polygon); --current sector's corner coordinate
  i := -1;
  <<yloop>>
  LOOP
    IF (Y > Ymax) THEN  
        EXIT;
    END IF;

    X := Xmin;
    <<xloop>>
    LOOP
      IF (X > Xmax) THEN
          EXIT;
      END IF;

      CPoint := ST_SetSRID(ST_MakePoint(X, Y), SRID);
      NextX := ST_X(ST_Project(CPoint, $2, radians(90))::geometry);
      NextY := ST_Y(ST_Project(CPoint, $3, radians(0))::geometry);

      i := i + 1;
      sectors[i] := ST_MakeEnvelope(X, Y, NextX, NextY, SRID);

      X := NextX;
    END LOOP xloop;
    CPoint := ST_SetSRID(ST_MakePoint(X, Y), SRID);
    NextY := ST_Y(ST_Project(CPoint, $3, radians(0))::geometry);
    Y := NextY;
  END LOOP yloop;

  RETURN ST_Collect(sectors);
END;
$body$
LANGUAGE 'plpgsql';

আপনি এটি এর মতো ব্যবহার করতে পারেন:

SELECT ST_AsGeoJSON(cell) FROM (
  SELECT (
    ST_Dump(
      makegrid_2d(
        ST_GeomFromText(
          'Polygon((35.099577 45.183417,47.283415 45.183417,47.283415 49.640445,35.099577 49.640445,35.099577 45.183417))',
          4326
        ),
         10000, -- width step in meters
         10000  -- height step in meters
       ) 
    )
  ) .geom AS cell
)q;

5

যে কোনও খাম, বহুভুজ বা মাল্টিপলিগনগুলির অভ্যন্তরে ফিশনেট, নিয়মিত গ্রিড, বহুভুজ গ্রিড, আয়তক্ষেত্রাকার গ্রিড তৈরি করতে এখানে একটি অনুকূলিত এবং দক্ষ অ্যালগরিদম রয়েছে। প্রায় কোনও এসআরআইডি হ্যান্ডেল করুন;

গিটহাব রেপো লিঙ্ক

এখানে চিত্র বর্ণনা লিখুন

DROP FUNCTION IF EXISTS PUBLIC.I_Grid_Regular(geometry, float8, float8);
CREATE OR REPLACE FUNCTION PUBLIC.I_Grid_Regular
( geom geometry, x_side float8, y_side float8, OUT geometry )
RETURNS SETOF geometry AS $BODY$ DECLARE
x_max DECIMAL;
y_max DECIMAL;
x_min DECIMAL;
y_min DECIMAL;
srid INTEGER := 4326;
input_srid INTEGER;
x_series DECIMAL;
y_series DECIMAL;
geom_cell geometry := ST_GeomFromText(FORMAT('POLYGON((0 0, 0 %s, %s %s, %s 0,0 0))',
                                        $3, $2, $3, $2), srid);
BEGIN
CASE ST_SRID (geom) WHEN 0 THEN
    geom := ST_SetSRID (geom, srid);
    RAISE NOTICE'SRID Not Found.';
ELSE
    RAISE NOTICE'SRID Found.';
END CASE;
input_srid := ST_srid ( geom );
geom := ST_Transform ( geom, srid );
x_max := ST_XMax ( geom );
y_max := ST_YMax ( geom );
x_min := ST_XMin ( geom );
y_min := ST_YMin ( geom );
x_series := CEIL ( @( x_max - x_min ) / x_side );
y_series := CEIL ( @( y_max - y_min ) / y_side );

RETURN QUERY With foo AS (
    SELECT
    ST_Translate( geom_cell, j * $2 + x_min, i * $3 + y_min ) AS cell
    FROM
        generate_series ( 0, x_series ) AS j,
        generate_series ( 0, y_series ) AS i
    ) SELECT ST_CollectionExtract(ST_Collect(ST_Transform ( ST_Intersection(cell, geom), input_srid)), 3)
    FROM foo where ST_intersects (cell, geom);
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE STRICT;

একটি সাধারণ ক্যোয়ারী সহ এটি ব্যবহার করুন; ইনপুটটি একটি বৈধ বহুভুজ, বহুগুণ বা খাম হতে হবে be

select I_Grid_Regular(st_setsrid(g.geom, 4326), .0001, .0001 ), geom from polygons limit 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.