আমার বহুভুজ বৈশিষ্ট্য রয়েছে এবং এর ভিতরে পয়েন্ট উত্পন্ন করতে সক্ষম হতে চাই। একটি শ্রেণিবিন্যাস কাজের জন্য আমার এটি দরকার।
একটি বহুভুতের ভিতরে না আসা পর্যন্ত এলোমেলো পয়েন্ট তৈরি করা কার্যকর হবে না কারণ এটি যে সময় নেয় এটি সত্যই অনাকাঙ্ক্ষিত।
আমার বহুভুজ বৈশিষ্ট্য রয়েছে এবং এর ভিতরে পয়েন্ট উত্পন্ন করতে সক্ষম হতে চাই। একটি শ্রেণিবিন্যাস কাজের জন্য আমার এটি দরকার।
একটি বহুভুতের ভিতরে না আসা পর্যন্ত এলোমেলো পয়েন্ট তৈরি করা কার্যকর হবে না কারণ এটি যে সময় নেয় এটি সত্যই অনাকাঙ্ক্ষিত।
উত্তর:
বহুভুজকে ত্রিভুজগুলিতে দ্রবীভূত করে শুরু করুন, তারপরে সেগুলির মধ্যে পয়েন্ট তৈরি করুন । (অভিন্ন বিতরণের জন্য, প্রতিটি ত্রিভুজকে এর ক্ষেত্রফল অনুযায়ী ওজন করুন))
আপনি যেমন এই প্রশ্নটিতে একটি QGIS ট্যাগ রেখেছেন: একটি সীমানা স্তর সহ র্যান্ডম পয়েন্টস সরঞ্জামটি ব্যবহার করা যেতে পারে।
আপনি যদি কোডটির সন্ধান করছেন তবে অন্তর্নিহিত প্লাগইন উত্স কোডটি সহায়তা করা উচিত।
আপনি বহুভুজটির ব্যাপ্তি নির্ধারণ করতে পারেন, তারপরে সেই এক্সেটেন্টগুলির মধ্যে এক্স এবং ওয়াই মানগুলির জন্য এলোমেলো সংখ্যা জেনারেশনকে সীমাবদ্ধ করতে পারেন।
বেসিক প্রক্রিয়া: 1) ম্যাক্সেক্স, ম্যাক্সি, মিনেক্স, বহুভুজের শীর্ষাংশের ক্ষুদ্র ক্ষুদ্র অংশ নির্ণয় করুন 2) এই মানগুলি সীমানা হিসাবে ব্যবহার করে এলোমেলো পয়েন্ট উত্পন্ন করুন 3) আপনার বহুভুজের সাথে ছেদ করার জন্য প্রতিটি পয়েন্ট পরীক্ষা করুন, 4) যখন মোড়কে সন্তুষ্ট করার জন্য পর্যাপ্ত পয়েন্ট রয়েছে তখন জেনারেশন বন্ধ করুন পরীক্ষা
ছেদ পরীক্ষার জন্য এখানে একটি অ্যালগরিদম (সি #) দেওয়া হল:
bool PointIsInGeometry(PointCollection points, MapPoint point)
{
int i;
int j = points.Count - 1;
bool output = false;
for (i = 0; i < points.Count; i++)
{
if (points[i].X < point.X && points[j].X >= point.X || points[j].X < point.X && points[i].X >= point.X)
{
if (points[i].Y + (point.X - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < point.Y)
{
output = !output;
}
}
j = i;
}
return output;
}
কিছু ভাল গ্রন্থাগার আছে যা আপনার জন্য বেশিরভাগ ভারী উত্তোলন করে do
পাইথনে [সুদৃশ্য] [1] ব্যবহারের উদাহরণ।
import random
from shapely.geometry import Polygon, Point
def get_random_point_in_polygon(poly):
minx, miny, maxx, maxy = poly.bounds
while True:
p = Point(random.uniform(minx, maxx), random.uniform(miny, maxy))
if poly.contains(p):
return p
p = Polygon([(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)])
point_in_poly = get_random_point_in_polygon(mypoly)
অথবা .representative_point()
অবজেক্টের মধ্যে বিন্দু পেতে ব্যবহার করুন (ডেইন দ্বারা উল্লিখিত):
জ্যামিতিক অবজেক্টের মধ্যে থাকা গ্যারান্টিযুক্ত একটি সুলভ গণনাকারী পয়েন্টটি প্রদান করে।
poly.representative_point().wkt
'POINT (-1.5000000000000000 0.0000000000000000)'
[1]: https://shapely.readthedocs.io
representative_point
পদ্ধতিটিও ব্যবহার করতে পারেন : শেডলি.ড্রেডহেডসকস.আইও
আর যদি বিকল্প ?spsample
হয় তবে sp
প্যাকেজে দেখুন। বহুভুজগুলি আর জিডিএল প্যাকেজে অন্তর্নির্মিত যে কোনও জিডিএল-সমর্থিত বিন্যাস থেকে পড়তে পারে এবং তারপরেওspsample
বিভিন্ন নমুনা বিকল্পের সাহায্যে সরাসরি আমদানিকৃত বস্তুটিতে কাজ করে।
আমি এমন একটি প্রস্তাব দিতে চাই যা জিআইএস বিশ্লেষণের ক্ষেত্রে খুব কম প্রয়োজন। বিশেষত, এর জন্য কোনও বহুভুজকে ত্রিকোণাকুলের প্রয়োজন হয় না।
সিউডোকোডে প্রদত্ত নিম্নলিখিত অ্যালগরিদমটি মৌলিক তালিকা পরিচালনার ক্ষমতা ছাড়াও কিছু সাধারণ ক্রিয়াকে বোঝায় (অন্তর্ভুক্ত করুন, দৈর্ঘ্য সংযোজন, সাজান, সূক্ষ্ম তালিকা তৈরি করুন, এবং সংলগ্ন) এবং বিরতিতে র্যান্ডম ভাসমানের প্রজন্ম [0, 1):
Area: Return the area of a polygon (0 for an empty polygon).
BoundingBox: Return the bounding box (extent) of a polygon.
Width: Return the width of a rectangle.
Height: Return the height of a rectangle.
Left: Split a rectangle into two halves and return the left half.
Right: ... returning the right half.
Top: ... returning the top half.
Bottom: ... returning the bottom half.
Clip: Clip a polygon to a rectangle.
RandomPoint: Return a random point in a rectangle.
Search: Search a sorted list for a target value. Return the index
of the last element less than the target.
In: Test whether a point is inside a polygon.
এগুলি প্রায় কোনও জিআইএস বা গ্রাফিক্স প্রোগ্রামিং পরিবেশে উপলব্ধ (এবং কোড না থাকলে সহজ) to Clip
অধঃপতিত বহুভুজগুলি অবশ্যই ফিরিয়ে আনবে না (এটি হ'ল শূন্য অঞ্চলযুক্ত)।
পদ্ধতিটি SimpleRandomSample
দক্ষতার সাথে বহুভুজের মধ্যে এলোমেলোভাবে বিতরণ করা পয়েন্টগুলির একটি তালিকা অর্জন করে। এটি একটি মোড়ক জন্যSRS
, যা প্রতিটি টুকরোকে দক্ষতার সাথে নমুনা দেওয়ার জন্য যথেষ্ট পরিমাণে কমপ্যাক্ট না হওয়া পর্যন্ত বহুভুজকে ছোট ছোট টুকরো টুকরো করে। এটি করার জন্য, প্রতিটি টুকরোকে কত পয়েন্ট বরাদ্দ করতে হবে তা নির্ধারণ করতে এটি এলোমেলো সংখ্যার একটি প্রাক্পম্পিউটেড তালিকা ব্যবহার করে।
পরামিতি পরিবর্তন করে এসআরএসকে "টিউন" করা যায় t
। এটি সর্বাধিক সীমাবদ্ধ বাক্স: বহুভুজ অঞ্চল অনুপাত যা সহ্য করা যায়। এটিকে ছোট (তবে 1 এর বেশি) তৈরি করা বেশিরভাগ বহুভুজকে অনেক টুকরো টুকরো টুকরো করে দেবে; এটিকে বড় করে তোলার ফলে কয়েকটি বহুভুজের জন্য বহু পরীক্ষার পয়েন্টগুলি প্রত্যাখ্যান করা হতে পারে (স্লিভারযুক্ত, বা গর্তে পূর্ণ) এটি গ্যারান্টি দেয় যে মূল বহুভুজের নমুনার সর্বাধিক সময় অনুমানযোগ্য।
Procedure SimpleRandomSample(P:Polygon, N:Integer) {
U = Sorted list of N independent uniform values between 0 and 1
Return SRS(P, BoundingBox(P), U)
}
পরবর্তী প্রক্রিয়াটি প্রয়োজন হলে নিজেকে পুনরাবৃত্তভাবে ডাকে। রহস্যজনক প্রকাশ t*N + 5*Sqrt(t*N)
রক্ষণশীলভাবে কতগুলি পয়েন্ট প্রয়োজন হবে তার উপরের সীমাটি অনুমান করে, সুযোগের পরিবর্তনশীলতার জন্য অ্যাকাউন্টিং। এটি ব্যর্থ হওয়ার সম্ভাবনা হ'ল প্রতি মিলিয়ন পদ্ধতি কলগুলিতে কেবল ০.০। আপনি যদি চান তবে এই সম্ভাবনা হ্রাস করতে 5 থেকে 6 বা 7 বৃদ্ধি করুন।
Procedure SRS(P:Polygon, B:Rectangle, U:List) {
N = Length(U)
If (N == 0) {Return empty list}
aP = Area(P)
If (aP <= 0) {
Error("Cannot sample degenerate polygons.")
Return empty list
}
t = 2
If (aP*t < Area(B)) {
# Cut P into pieces
If (Width(B) > Height(B)) {
B1 = Left(B); B2 = Right(B)
} Else {
B1 = Bottom(B); B2 = Top(B)
}
P1 = Clip(P, B1); P2 = Clip(P, B2)
K = Search(U, Area(P1) / aP)
V = Concatenate( SRS(P1, B1, U[1::K]), SRS(P2, B2, U[K+1::N]) )
} Else {
# Sample P
V = empty list
maxIter = t*N + 5*Sqrt(t*N)
While(Length(V) < N and maxIter > 0) {
Decrement maxIter
Q = RandomPoint(B)
If (Q In P) {Append Q to V}
}
If (Length(V) < N) {
Error("Too many iterations.")
}
}
Return V
}
যদি আপনার বহুভুজটি উত্তল এবং আপনি সমস্ত শিখুনগুলি জানেন তবে আপনি একটি নতুন বিন্দুর নমুনা করার জন্য শীর্ষবিন্দুগুলির একটি "এলোমেলো" উত্তল ওজনকে বিবেচনা করতে চাইতে পারেন যা উত্তল কুটির (এই ক্ষেত্রে বহুভুজ) এর অভ্যন্তরে শুয়ে থাকার নিশ্চয়তা রয়েছে।
উদাহরণস্বরূপ বলুন যে আপনি একটি এন পার্শ্বযুক্ত উত্তল বহুভুজ আছে শীর্ষে
V_i, i={1,..,N}
তারপরে এলোমেলোভাবে এন উত্তল ওজন উত্পন্ন করুন
w_1,w_2,..,w_N such that ∑ w_i = 1; w_i>=0
এলোমেলোভাবে নমুনাযুক্ত পয়েন্টটি পরে দেওয়া হয়
Y= ∑ w_i*V_i
এন উত্তল ওজনের নমুনার বিভিন্ন উপায় থাকতে পারে
যখন আপনার বহুভুজ খুব মারাত্মকভাবে নন-উত্তল নয় তখন আপনি প্রথমে এটিকে উত্তল কুঁচকে রূপান্তর করতে বিবেচনা করতে পারেন। এটি কমপক্ষে আপনার বহুভুজের বাইরে থাকা পয়েন্টগুলির সংখ্যা সীমিত করা উচিত।
গ্রাস জিআইএস (এক কমান্ড) v.random ব্যবহার করে টাস্কটি সমাধান করা খুব সহজ ।
ম্যানুয়াল পৃষ্ঠা থেকে নির্বাচিত বহুভুজগুলিতে (এখানে র্যালি, এনসি শহরের জিপ কোড অঞ্চলগুলি) কীভাবে 3 টি এলোমেলো পয়েন্ট যুক্ত করতে হবে তার উদাহরণের নীচে। এসকিউএল "যেখানে" বিবৃতি সংশোধন করে বহুভুজ (গুলি) নির্বাচন করা যেতে পারে।
উত্তর লিঙ্ক
https://gis.stackexchange.com/a/307204/103524
বিভিন্ন পদ্ধতির ব্যবহার করে তিনটি অ্যালগরিদম।
ফাংশন ================================================== ==================
CREATE OR REPLACE FUNCTION public.I_Grid_Point_Distance(geom public.geometry, x_side decimal, y_side decimal)
RETURNS public.geometry AS $BODY$
DECLARE
x_min decimal;
x_max decimal;
y_max decimal;
x decimal;
y decimal;
returnGeom public.geometry[];
i integer := -1;
srid integer := 4326;
input_srid integer;
BEGIN
CASE st_srid(geom) WHEN 0 THEN
geom := ST_SetSRID(geom, srid);
----RAISE NOTICE 'No SRID Found.';
ELSE
----RAISE NOTICE 'SRID Found.';
END CASE;
input_srid:=st_srid(geom);
geom := st_transform(geom, srid);
x_min := ST_XMin(geom);
x_max := ST_XMax(geom);
y_max := ST_YMax(geom);
y := ST_YMin(geom);
x := x_min;
i := i + 1;
returnGeom[i] := st_setsrid(ST_MakePoint(x, y), srid);
<<yloop>>
LOOP
IF (y > y_max) THEN
EXIT;
END IF;
CASE i WHEN 0 THEN
y := ST_Y(returnGeom[0]);
ELSE
y := ST_Y(ST_Project(st_setsrid(ST_MakePoint(x, y), srid), y_side, radians(0))::geometry);
END CASE;
x := x_min;
<<xloop>>
LOOP
IF (x > x_max) THEN
EXIT;
END IF;
i := i + 1;
returnGeom[i] := st_setsrid(ST_MakePoint(x, y), srid);
x := ST_X(ST_Project(st_setsrid(ST_MakePoint(x, y), srid), x_side, radians(90))::geometry);
END LOOP xloop;
END LOOP yloop;
RETURN
ST_CollectionExtract(st_transform(ST_Intersection(st_collect(returnGeom), geom), input_srid), 1);
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;
একটি সাধারণ ক্যোয়ারী সহ ফাংশনটি ব্যবহার করুন, জ্যামিতিটি অবশ্যই বৈধ এবং বহুভুজ, বহু-বহুভুজ বা খামের হতে হবে
SELECT I_Grid_Point_Distance(geom, 50, 61) from polygons limit 1;
ফলাফল ================================================= =====================
নিক্লাস আভান অ্যালগরিদমের উপর ভিত্তি করে দ্বিতীয় ফাংশন । যে কোনও এসআরআইডি হ্যান্ডেল করার চেষ্টা করেছেন।
আমি অ্যালগরিদমে নিম্নলিখিত পরিবর্তনগুলি প্রয়োগ করেছি।
ফাংশন ================================================== ==================
CREATE OR REPLACE FUNCTION I_Grid_Point(geom geometry, x_side decimal, y_side decimal, spheroid boolean default false)
RETURNS SETOF geometry AS $BODY$
DECLARE
x_max decimal;
y_max decimal;
x_min decimal;
y_min decimal;
srid integer := 4326;
input_srid integer;
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;
CASE spheroid WHEN false THEN
RAISE NOTICE 'Spheroid False';
srid := 4326;
x_side := x_side / 100000;
y_side := y_side / 100000;
else
srid := 900913;
RAISE NOTICE 'Spheroid True';
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);
RETURN QUERY
WITH res as (SELECT ST_SetSRID(ST_MakePoint(x, y), srid) point FROM
generate_series(x_min, x_max, x_side) as x,
generate_series(y_min, y_max, y_side) as y
WHERE st_intersects(geom, ST_SetSRID(ST_MakePoint(x, y), srid))
) select ST_TRANSFORM(ST_COLLECT(point), input_srid) from res;
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE STRICT;
একটি সাধারণ ক্যোয়ারী সহ এটি ব্যবহার করুন।
SELECT I_Grid_Point(geom, 22, 15, false) from polygons;
ফলাফল ================================================= ==================
ফাংশন ================================================= =================
CREATE OR REPLACE FUNCTION I_Grid_Point_Series(geom geometry, x_side decimal, y_side decimal, spheroid boolean default false)
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;
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;
CASE spheroid WHEN false THEN
RAISE NOTICE 'Spheroid False';
else
srid := 900913;
RAISE NOTICE 'Spheroid True';
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
SELECT st_collect(st_setsrid(ST_MakePoint(x * x_side + x_min, y*y_side + y_min), srid)) FROM
generate_series(0, x_series) as x,
generate_series(0, y_series) as y
WHERE st_intersects(st_setsrid(ST_MakePoint(x*x_side + x_min, y*y_side + y_min), srid), geom);
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE STRICT;
একটি সাধারণ ক্যোয়ারী সহ এটি ব্যবহার করুন।
SELECT I_Grid_Point_Series(geom, 22, 15, false) from polygons;
ফলাফল ================================================= =========================