পোস্টজিআইএসে একটি লাইন এক্সট্রোপোলেট করা


19

আমি রেখার বিন্দুটি রেখার জন্য একটি রেখাংশটি খুঁজে পেতে চাইছি তবে 'পিছনে' পথের তৃতীয়, অর্থাৎ পয়েন্ট new, প্রদত্ত পয়েন্ট Aএবং Bনীচে খুঁজতে চেষ্টা করছি :

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

একটি লাইন দেওয়া হয়েছে, আমি এটির সাথে কোনও নির্দিষ্ট শতাংশে একটি অবস্থান পেতে এটির সাথে বিভক্ত করতে পারি:

=# select st_line_interpolate_point(
   st_makeline('0101000020E6100000300DC347C49418C03EE8D9ACFAA44A40', 
               '0101000020E6100000FB743C66A03218C0CDCCCCCCCC7C4A40'), 
   0.333);
0101000020E6100000ED45B41D537718C069C6A2E9EC984A40

আমি বিপরীত দিকে লাইন বরাবর একটি বিন্দু খুঁজে পেতে একটি নেতিবাচক সংখ্যা প্রবেশ করার চেষ্টা করেছি, কিন্তু এটি ব্যর্থ হয়েছে কারণ দ্বিখণ্ডনের যুক্তিটি সীমার মধ্যে থাকতে হবে [0, 1]

আমি প্রথমে লাইনটি স্কেলিংয়ের কথা ভেবেছিলাম, তবে এটি লাইনটির কেন্দ্রটিকে উত্স হিসাবে ব্যবহার করে না, তাই এটি আমার উদ্দেশ্যে অকেজো।

উত্তর:


21

এর আগে আমি একই ধরণের সমস্যার সমাধান করেছি অন্য উপায়টি হ'ল নিম্নলিখিত পদক্ষেপগুলিতে বিভক্ত হওয়া।

-- get the points A and B given a line L
A := ST_STARTPOINT(L);
B := ST_ENDPOINT(L);

-- get the bearing from point B --> A
azimuth := ST_AZIMUTH(B,A);

-- get the length of the line A --> B
length := ST_DISTANCE(A,B);
newlength := length + (length * (1/3));   -- increase the line length by 1/3

-- create a new point 1/3 as far away from A as B is from A
newpoint := ST_TRANSLATE(A, sin(azimuth) * newlength, cos(azimuth) * newlength);

সম্পাদনা: নতুন দৈর্ঘ্যের অ্যাসাইনমেন্টটি স্থির করে রাখুন যাতে এটি 1/3 এর পরিবর্তে দৈর্ঘ্য 1/3 হয় এবং ডায়াগ্রামের সাথে মিলিয়ে A & B পরিবর্তন করে।


আমরা একটি বিজয়ী আছে! অনেক বেশি বোধগম্য।
EoghanM

এটি বেশ দুর্দান্ত
নাথান ডাব্লু

ধন্যবাদ। কনট্যুর লাইনের মধ্যে আমি ম্যানুয়ালি ইন্টারপোলটিং করছিলাম এমন কোনও কাজ থেকে আমি এই স্নিপেটটি পেয়েছিলাম - প্রমাণিত হয়েছে যে আমি কনট্যুরগুলির সাথে কী করার চেষ্টা করছিলাম তা নষ্ট হয়েছিল, তবে এই স্নিপেটটি অন্য কাউকে সাহায্য করতে পেরে আনন্দিত! :)
জয়ডেন

6

এটি দিয়ে সমাধান করেছেন:

F = 1.3333
st_affine(A, F, 0, 
             0, F, 
            (F-1)*-st_x(st_line_interpolate_point(st_makeline(A, B), 0.5)), 
            (F-1)*-st_y(st_line_interpolate_point(st_makeline(A, B), 0.5))
          )

ব্যাখ্যা:

(২-ডি) স্কেলিংয়ের উত্স হিসাবে লাইন বিভাগের মধ্যবিন্দুটিকে ধরে 1.3333 এর একটি ফ্যাক্টর দ্বারা সূচনা পয়েন্টটি স্কেল করুন।

গ্রাফ পেপার বের করুন!

http://en.wikipedia.org/wiki/Affine_transformation


2

আমি এর জন্য একটি ফাংশন লিখেছি:

CREATE OR REPLACE FUNCTION st_extend (
    geom geometry,
    head_rate double precision,
    head_constant double precision,
    tail_rate double precision,
    tail_constant double precision)
  RETURNS geometry AS
$BODY$
-- Extends a linestring.
-- First segment get extended by length * head_rate + head_constant.
-- Last segment get extended by length * tail_rate + tail_constant.
--
-- References:
-- http://blog.cleverelephant.ca/2015/02/breaking-linestring-into-segments.html
-- /gis//a/104451/44921
-- /gis//a/16701/44921
WITH segment_parts AS (
SELECT
(pt).path[1]-1 as segment_num
,
CASE
WHEN
  (nth_value((pt).path, 2) OVER ()) = (pt).path
AND
  (last_value((pt).path) OVER ()) = (pt).path
THEN
  3
WHEN
  (nth_value((pt).path, 2) OVER ()) = (pt).path
THEN
  1
WHEN
  (last_value((pt).path) OVER ()) = (pt).path
THEN
  2
ELSE
  0
END AS segment_flag
,
(pt).geom AS a
,
lag((pt).geom, 1, NULL) OVER () AS b
FROM ST_DumpPoints($1) pt
)
,
extended_segment_parts
AS
(
SELECT
  *
  ,
  ST_Azimuth(a,b) AS az1
  ,
  ST_Azimuth(b,a) AS az2
  ,
  ST_Distance(a,b) AS len
FROM
segment_parts
where b IS NOT NULL
)
,
expanded_segment_parts
AS
(
SELECT
  segment_num
  ,
  CASE
  WHEN
    bool(segment_flag & 2)
  THEN
    ST_Translate(b, sin(az2) * (len*tail_rate+tail_constant), cos(az2) * (len*tail_rate+tail_constant))
  ELSE
    a
  END
  AS a
  ,
  CASE
  WHEN
    bool(segment_flag & 1)
  THEN
    ST_Translate(a, sin(az1) * (len*head_rate+head_constant), cos(az1) * (len*head_rate+head_constant))
  ELSE
    b
  END
  AS b
FROM extended_segment_parts
)
,
expanded_segment_lines
AS
(
SELECT
  segment_num
  ,
  ST_MakeLine(a, b) as geom
FROM
expanded_segment_parts
)
SELECT
  ST_LineMerge(ST_Collect(geom ORDER BY segment_num)) AS geom
FROM expanded_segment_lines
;
$BODY$
LANGUAGE sql;

ব্যবহার:

SELECT st_extend(
st_makeline(
  '0101000020E6100000300DC347C49418C03EE8D9ACFAA44A40', 
  '0101000020E6100000FB743C66A03218C0CDCCCCCCCC7C4A40'
),
1.333::double precision,
0::double precision,
1::double precision,
0::double precision
);

মনে রাখবেন যে এটি দীর্ঘতর লাইনস্ট্রিং দেয় তবে শেষ পয়েন্টটি দেয় না।

গিটহাব গিস্টের কোড (আপনি যদি এখানে উপস্থাপন করেন তবে আমি সেখানেও একটি তারাটির প্রশংসা করব)

প্যারামিটারগুলির বিবরণ (আপনি যদি স্কয়ার ফাংশনের মন্তব্যে এগুলি মিস করেছেন):

  • প্রথম বিভাগের দৈর্ঘ্য হবে মূল_ দৈর্ঘ্য * হেড_রেট + হেড_কনস্ট্যান্ট।
  • আপনি যদি এটি দ্বিগুণ করতে চান তবে মাথা হার 2, ধ্রুবক 0।
  • আমরা হাঙ্গেরিতে সাধারণত EOV প্রক্ষেপণটি ব্যবহার করি যা মিটার ভিত্তিক। সুতরাং আমি যদি লাইনটির শেষে 2 মিটার যুক্ত করতে চাই, তবে আমি লেজটি সেট করবো: হার 1 এবং টেল_কন্ট্যান্ট 2 এ।

এটি খুব ভাল কাজ করে। আপনি কি হেড_রেট, হেড_কনস্ট্যান্ট, টেল_রেট এবং লেজ_কন্ট্যান্ট সম্পর্কে কিছু তথ্য যুক্ত করতে পারেন? সেগুলি এখানে বা আপনার গিটহাবে ব্যাখ্যা করা হয়নি। আমি ধরে নিচ্ছি যে প্রারম্ভের আগে লাইন এক্সটেনশনের জন্য লাইন এক্সটেনশনের জন্য শীর্ষ হার = স্কেল ফ্যাক্টর এবং প্রারম্ভের আগে লাইনের সম্প্রসারণের জন্য = স্কেল ফ্যাক্টর। ধ্রুবকরা কীভাবে কাজ করবে? তাদের কী প্রভাব আছে?
জবল্ক

এটা মন্তব্যে। প্রথম বিভাগের দৈর্ঘ্য হবে original_length * head_rate + head_constant। আপনি যদি এটি দ্বিগুণ করতে চান তবে মাথা হার 2, ধ্রুবক 0 হয় hung আমরা হাঙ্গারিতে সাধারণত EOV প্রক্ষেপণ ব্যবহার করি যা মিটার ভিত্তিক is সুতরাং আমি যদি লাইনের শেষের দিকে 2 মিটার যুক্ত করতে চাই, তবে আমি লেজটি সেট করবো: হার 1 এবং লেজ_কন্ট্যান্ট 2
সিজিবার্থ অ্যাডাম

ধন্যবাদ! এবং এই ফাংশন ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ। এটি নিখুঁতভাবে কাজ করে এবং এটি দ্রুত চলে।
জবল্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.