নির্দিষ্ট ফল / দীর্ঘ পয়েন্টের 30km ব্যাসার্ধের মধ্যে সমস্ত ফলাফল ফেরত দেবেন?


21

আমার কাছে একটি কলামের সাথে একটি টেবিল the_geomরয়েছে যার মতো ডেটা রয়েছে:

0103000020E61000000100000005000000CE473AACFA071E40F27FB23340744740336FE841C6231E40873BED903F744740FC150A0ACE231E40D19E2684637647409C9B443D00081E409A9AF82664764740CE473AACFA071E40F27FB23340744740

যা ফাংশন প্রয়োগ করার সময় ST_AsEWKT(the_geom)ফিরে আসে:

SRID=4326;POLYGON((7.5077921782085 46.9082092877942,7.53493597966353 46.9081898840296,7.53496566473541 46.9249119938446,7.50781341296434 46.9249314035307,7.5077921782085 46.9082092877942))

আমার নির্দিষ্ট ডেটা / লম্বা পয়েন্টের 30km ব্যাসার্ধের সমস্ত ডেটা নির্বাচন করা দরকার, উদাহরণস্বরূপ:

  • ল্যাট = 46.8167
  • lng = 6.9333

তবে যখনই আমি ব্যবহার করার চেষ্টা করেছি ST_Distance(), আমি সর্বদা 1 এর চেয়ে কম মান পেয়েছি এবং ST_DWithin()সর্বদা সত্য ব্যবহার করে এসেছি ।

উত্তর:


23

নির্দিষ্ট দূরত্বের মধ্যে ডেটা পেতে দয়া করে PostgreSQL এর জন্য নিম্নলিখিত কোয়েরিটি দেখুন। আমি আশা করি এটি সাহায্য করবে

SELECT *
FROM your_table
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(your_lon,your_lat)) <= radius_mi * 1609.34

1
এটি দিয়ে কাজ করতে সক্ষম হয়েছিল: SET * থেকে MyTable WHOE GeometryType (ST_Centroid (the_geom)) = 'POINT' এবং ST_Distance_Sphere (ST_Point (ST_X (S_Centroid (the_geom))), ST_Y (ST_Cendroid (the_geom)), (6.93) (এস 33) , 46.8167)) <= 18 * 1609.34
dan2k3k4

এটি দুর্দান্ত :)
ফরহাত আব্বাস

2
অন্য যে কেউ ভাবছেন, 1609.34 চিত্রটি মাইল প্রতি মাইল, যা বেস ইউনিট পোস্টগ্রিস ব্যবহার করছে। সুতরাং 1000. দ্বারা কিলোমিটার করতে হবে, সম্ভবত সংখ্যাবৃদ্ধি
1mike12

2
পেডেন্টিক নোট: এটি 1609.344 হুবহু (সংজ্ঞা অনুসারে)
ব্যারিকার্টার

6

মনে হচ্ছে আপনি জ্যামিতি কলামে আপনার জ্যামিতিটি সঞ্চয় করছেন, কোনও ভূগোলের কলামে নয়।
এটি ঠিক আছে, তবে ফাংশন ST_ দূরত্ব সর্বদা মিটারের পরিবর্তে প্রক্ষেপণ ইউনিটে পরিমাপ ফিরে আসবে। আপনার ক্ষেত্রে (4326), এটি ডিগ্রি হবে।
কেবলমাত্র ST_Within সহ একটি বাফার ব্যবহার করা কোনওভাবেই কাজ করবে না, কারণ ST_Buffer ডিগ্রি দিয়েও পরিমাপ করা হবে।

আপনি জ্যামিতির পরিবর্তে ভূগোল ব্যবহার করতে আপনার ডেটা রূপান্তর করতে পারেন, বা আপনি নিজের বিন্দুটিকে এমন কিছু প্রক্ষেপণে রূপান্তর করতে পারেন যা মিটার, বাফার ব্যবহার করে, তারপরে কী রয়েছে তা দেখতে 4326 এ ফিরে রূপান্তর করতে পারেন:

SELECT
    *
FROM <your data>
WHERE ST_Within(the_geom, 
                ST_Transform(ST_Buffer(ST_Transform(ST_SetSRID(ST_MakePoint(6.9333, 46.8167), 4326), 3857), 30000), 4326)) = 1

এটি পয়েন্টটি 3857 এ প্রবর্তন করে, যা ওয়েব মানচিত্রের সাথে জনপ্রিয় একটি অভিক্ষেপ। তারপরে এটি 30,000 মিটার বাফার করে এটি ST_Within এ যাওয়ার আগে এটি 4326 এ ফিরে প্রত্যাবর্তন করে।


সিউডো-মার্কেটর বাদে দূরত্বের জন্য অবিশ্বাস্য, সুতরাং তথ্য নিরক্ষীয় অঞ্চলের কাছাকাছি না হলে ফলাফলগুলি বিশেষত 30 কিলোমিটারের দূরত্বে বন্ধ থাকবে।
ভিন্স

6

আমার বিশ্বে একটি কাস্টম এসআরআইডি (গুগল ম্যাপের জন্য) ব্যবহার করে এরকম কিছু কাজ করা হয়েছে:

SELECT * FROM addresses WHERE ST_DWithin(location, ST_SetSRID(ST_MakePoint(longitude, latitude), 3785), radius);

যেখানে ধরণ locationএকটি জ্যামিতি (পয়েন্ট, 3785), এবং longitude, latitudeএবং radiusহয় ভাসে (যেমন -100, 44, 100W / 44N / 30 "ইউনিট" এর জন্য 30 - নিচে দেখুন)

দেখুন অন্য কোনও বস্তুর ব্যাসার্ধের মধ্যে সমস্ত বস্তু সন্ধান করার সর্বোত্তম উপায় কী? পোস্টগিস ডক্সে:

ST_DWithin(geometry, geometry, distance)ফাংশন একটি সূচীবদ্ধ দূরত্ব অনুসন্ধান সম্পাদন একটি কুশলী উপায়। এটি দূরত্বের ব্যাসার্ধটি ঘিরে রাখার জন্য পর্যাপ্ত পরিমাণে অনুসন্ধানের আয়তক্ষেত্র তৈরি করে ফলাফলের সূচীত উপসেটটিতে একটি সঠিক দূরত্ব অনুসন্ধান করে কাজ করে।

আপডেট: ইউনিটগুলি এসআরআইডি ৩8585৮ এর জন্য মাইল নয় ... তারা মনে হয় হয় রেডিয়ান বা ডিগ্রি বা এর মতো কিছু। তবে আমার এসআরআইডি-র স্পেসিফিকেশন বলছে এর ইউনিটগুলি মিটার বা ডিগ্রি এবং এটি অবশ্যই কোনও একটি নয়, কমপক্ষে কোনও রূপান্তর ছাড়াই নয়:

alex=# select * from spatial_ref_sys where srid=3785; srid | auth_name | auth_srid | srtext | proj4text
3785 | EPSG | 3785 | PROJCS["Popular Visualisation CRS / Mercator (deprecated)",GEOGCS["Popular Visualisation CRS",DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137,0,AUTHORITY["EPSG","7059"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6055"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4055"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3785"],AXIS["X",EAST],AXIS["Y",NORTH]] | +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs


3785 (আপনার পোস্টে) এবং 3857 এর মধ্যে পার্থক্য কী?
সুর ​​করেছেন

তারা বিভিন্ন অনুমান। 3875 বনাম 3857 - আমি জানিনা যে একজনের চেয়ে অন্যটি ভাল কিনা
অ্যালেক্সচফি

1
"EPSG 3785 অন্যথায় অভিন্ন ইপিএসজি 3857 এর পক্ষে অবহিত করা হয়েছে" - github.com/geo/geo/pull/61
ইয়ারিন

2

আমি মনে করি এটি কাজ করা উচিত:

SELECT gid FROM table 
WHERE ST_DWithin(the_geom, ST_SetSRID(ST_Point(6.9333, 46.8167), 4326), 30000)

3
যদি আপনি ভূগোলের জন্য কাজ করে যা_সামান্যকে ফেলে দেয়। st_dwithin (ভূগোল (the_geom), ভূগোল (<পয়েন্ট, 4326>), 30000)
cavila
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.