আর্কজিআইএস ডেস্কটপ এবং / অথবা আর ব্যবহার করে নিকটতম পয়েন্টগুলি (ল্যাট / লম্বায় দেওয়া) কিমি থেকে দূরত্ব গণনা করুন?


10

আমার কাছে আর্কজিআইএসে দুটি পয়েন্টের ডেটাসেট রয়েছে, যার দুটিই ডাব্লুজিএস 84 ল্যাট / লং কো-অর্ডিনেটে দেওয়া হয়েছে এবং পয়েন্টগুলি পুরো বিশ্ব জুড়ে ছড়িয়ে রয়েছে। আমি ডেটাসেট বি এর প্রতিটি বিন্দুতে ডেটাসেট এ এর ​​নিকটতম পয়েন্টটি খুঁজতে এবং কিলোমিটারের মধ্যে তাদের মধ্যে দূরত্ব পেতে চাই।

এটি কাছাকাছি সরঞ্জামটির নিখুঁত ব্যবহারের মতো বলে মনে হচ্ছে তবে এটি আমাকে ইনপুট পয়েন্টগুলির সমন্বয় ব্যবস্থাতে ফলাফল দেয়: এটি হল দশমিক ডিগ্রি। আমি জানি যে আমি ডেটাটি পুনঃপ্রজেক্ট করতে পারি, তবে আমি একত্রিত হয়েছি ( এই প্রশ্ন থেকে ) যে বিশ্বজুড়ে সঠিক দূরত্ব দেবে এমন একটি অভিক্ষেপ খুঁজে পাওয়া কঠিন (যদি অসম্ভব না হয়) is

এই প্রশ্নের উত্তরগুলি হ্যাভসাইন সূত্রটি ব্যবহার করে সরাসরি অক্ষাংশ-দ্রাঘিমাংশের সমন্বয়গুলি ব্যবহার করে দূরত্ব গণনা করে। আরকিজিআইএস ব্যবহার করে কিমিটারে এটি করার এবং ফল পাওয়ার কোনও উপায় আছে? যদি তা না হয় তবে এর কাছে যাওয়ার সর্বোত্তম উপায় কী?

উত্তর:


6

যদিও এটি কোনও আর্কজিআইএস সমাধান নয়, আপনার সমস্যাটি আরকে আপনার পয়েন্টগুলি রফতানি করে এবং প্যাকেজ spDists থেকে ফাংশনটি ব্যবহার করে আর এ সমাধান করা যেতে পারে sp। যদি আপনি সেট ফাংশন, একটি রেফারেন্স বিন্দু (গুলি) এবং পয়েন্ট একটি ম্যাট্রিক্স মধ্যে দূরত্ব খুঁজে বের করে কিলোমিটারের মধ্যে longlat=T

একটি দ্রুত এবং নোংরা উদাহরণ এখানে:

library(sp)
## Sim up two sets of 100 points, we'll call them set a and set b:
a <- SpatialPoints(coords = data.frame(x = rnorm(100, -87.5), y = rnorm(100, 30)), proj4string=CRS("+proj=longlat +datum=WGS84"))
b <- SpatialPoints(coords = data.frame(x = rnorm(100, -88.5), y = rnorm(100, 30.5)), proj4string=CRS("+proj=longlat +datum=WGS84"))

## Find the distance from each point in a to each point in b, store
##    the results in a matrix.
results <- spDists(a, b, longlat=T)

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

কোনও লুপিংয়ের দরকার নেই, আপনি ফাংশনটিকে দুটি সেট পয়েন্ট দিতে পারেন এবং এটি প্রতিটি পয়েন্টের সংমিশ্রনের মধ্যে দূরত্ব সহ একটি ম্যাট্রিক্স ফিরিয়ে দেবে। উদাহরণ কোড অন্তর্ভুক্ত করতে সম্পাদিত উত্তর।
অ্যালেন

3

এটি কোনও আর্কজিআইএস সমাধান নয়, তবে একটি স্থানিক ডাটাবেসে একটি রাউন্ড আর্থ ডেটা মডেল ব্যবহার করা কৌশলটি কার্যকর করবে। এটি সমর্থন করে ডাটাবেসে পৃথিবীর দূরত্ব গণনা করা বেশ সহজ হবে। আমি আপনাকে দুটি পঠন প্রস্তাব করতে পারি:

http://postgis.net/workshops/postgis-intro/geography.html

http://blog.safe.com/2012/08/round-earth-data-in-oracle-postgis-and-sql-server/


2

আপনার একটি দূরত্বের গণনা প্রয়োজন যা ল্যাট / লংয়ের সাথে কাজ করে। ভিনসেন্টি হ'ল আমি ব্যবহার করব (0.5 মিমি যথার্থতা)। আমি এর সাথে আগেও খেলেছি, এবং এটি ব্যবহার করা খুব কঠিন নয়।

কোডটি কিছুটা দীর্ঘ, তবে এটি কার্যকর হয়। ডাব্লুজিএসে দুটি পয়েন্ট দেওয়া, এটি কয়েক মিটার দূরত্বে ফিরে আসবে।

আপনি এটি আর্কজিআইএসে পাইথন স্ক্রিপ্ট হিসাবে ব্যবহার করতে পারেন বা অন্য স্ক্রিপ্টের চারপাশে এটি মোড়ানো করতে পারেন যা কেবলমাত্র দুটি পয়েন্ট শেফিলগুলিতে পুনরাবৃত্তি করে এবং আপনার জন্য একটি দূরত্বের ম্যাট্রিক্স তৈরি করে। অথবা, খুব সহজেই GENERATE_NEAR_TABLE- এর ফলাফলগুলি 2-3 নিকটবর্তী বৈশিষ্ট্যগুলি (পৃথিবীর বক্রতার জটিলতা এড়াতে) সন্ধানের সাথে খাওয়ানো সহজ।

import math

ellipsoids = {
    #name        major(m)   minor(m)            flattening factor
    'WGS-84':   (6378137,   6356752.3142451793, 298.25722356300003),
    'GRS-80':   (6378137,   6356752.3141403561, 298.25722210100002),
    'GRS-67':   (6378160,   6356774.5160907144, 298.24716742700002),

}

def distanceVincenty(lat1, long1, lat2, long2, ellipsoid='WGS-84'):
    """Computes the Vicenty distance (in meters) between two points
    on the earth. Coordinates need to be in decimal degrees.
    """
    # Check if we got numbers
    # Removed to save space
    # Check if we know about the ellipsoid
    # Removed to save space
    major, minor, ffactor = ellipsoids[ellipsoid]
    # Convert degrees to radians
    x1 = math.radians(lat1)
    y1 = math.radians(long1)
    x2 = math.radians(lat2)
    y2 = math.radians(long2)
    # Define our flattening f
    f = 1 / ffactor
    # Find delta X
    deltaX = y2 - y1
    # Calculate U1 and U2
    U1 = math.atan((1 - f) * math.tan(x1))
    U2 = math.atan((1 - f) * math.tan(x2))
    # Calculate the sin and cos of U1 and U2
    sinU1 = math.sin(U1)
    cosU1 = math.cos(U1)
    sinU2 = math.sin(U2)
    cosU2 = math.cos(U2)
    # Set initial value of L
    L = deltaX
    # Set Lambda equal to L
    lmbda = L
    # Iteration limit - when to stop if no convergence
    iterLimit = 100
    while abs(lmbda) > 10e-12 and iterLimit >= 0:
        # Calculate sine and cosine of lmbda
        sin_lmbda = math.sin(lmbda)
        cos_lmbda = math.cos(lmbda)
        # Calculate the sine of sigma
        sin_sigma = math.sqrt(
                (cosU2 * sin_lmbda) ** 2 + 
                (cosU1 * sinU2 - 
                 sinU1 * cosU2 * cos_lmbda) ** 2
        )
        if sin_sigma == 0.0:
            # Concident points - distance is 0
            return 0.0
        # Calculate the cosine of sigma
        cos_sigma = (
                    sinU1 * sinU2 + 
                    cosU1 * cosU2 * cos_lmbda
        )
        # Calculate sigma
        sigma = math.atan2(sin_sigma, cos_sigma)
        # Calculate the sine of alpha
        sin_alpha = (cosU1 * cosU2 * math.sin(lmbda)) / (sin_sigma)
        # Calculate the square cosine of alpha
        cos_alpha_sq = 1 - sin_alpha ** 2
        # Calculate the cosine of 2 sigma
        cos_2sigma = cos_sigma - ((2 * sinU1 * sinU2) / cos_alpha_sq)
        # Identify C
        C = (f / 16.0) * cos_alpha_sq * (4.0 + f * (4.0 - 3 * cos_alpha_sq))
        # Recalculate lmbda now
        lmbda = L + ((1.0 - C) * f * sin_alpha * (sigma + C * sin_sigma * (cos_2sigma + C * cos_sigma * (-1.0 + 2 * cos_2sigma ** 2)))) 
        # If lambda is greater than pi, there is no solution
        if (abs(lmbda) > math.pi):
            raise ValueError("No solution can be found.")
        iterLimit -= 1
    if iterLimit == 0 and lmbda > 10e-12:
        raise ValueError("Solution could not converge.")
    # Since we converged, now we can calculate distance
    # Calculate u squared
    u_sq = cos_alpha_sq * ((major ** 2 - minor ** 2) / (minor ** 2))
    # Calculate A
    A = 1 + (u_sq / 16384.0) * (4096.0 + u_sq * (-768.0 + u_sq * (320.0 - 175.0 * u_sq)))
    # Calculate B
    B = (u_sq / 1024.0) * (256.0 + u_sq * (-128.0 + u_sq * (74.0 - 47.0 * u_sq)))
    # Calculate delta sigma
    deltaSigma = B * sin_sigma * (cos_2sigma + 0.25 * B * (cos_sigma * (-1.0 + 2.0 * cos_2sigma ** 2) - 1.0/6.0 * B * cos_2sigma * (-3.0 + 4.0 * sin_sigma ** 2) * (-3.0 + 4.0 * cos_2sigma ** 2)))
    # Calculate s, the distance
    s = minor * A * (sigma - deltaSigma)
    # Return the distance
    return s

1

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

তবে এই পদ্ধতিটি আপনার ডেটাসেটের পয়েন্টের পরিমাণের উপর নির্ভর করবে। এটি বড় ডেটাসেটগুলির সাথে সঠিকভাবে কাজ করতে পারে না।


পরামর্শের জন্য ধন্যবাদ. তবে, এটি আমাকে কীভাবে সাহায্য করবে তা আমি দেখতে পাচ্ছি না। ডক্স অনুসারে ( help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… ) "দূরত্বটি ইনপুট বৈশিষ্ট্যগুলি সমন্বিত সিস্টেমের লিনিয়ার ইউনিটে রয়েছে" ", যা আমার ইনপুট বৈশিষ্ট্য হিসাবে ল্যাটে / দীর্ঘ সময়ে অবশ্যই আমাকে দশমিক ডিগ্রিতে ফলাফল দেবে? (এটি পরীক্ষা করার জন্য আমি এখানে
আরকিজিআইএস

এই ক্ষেত্রে, আমি সম্ভবত আপনার ডেটেবলে এক্স এবং ওয়াই ক্ষেত্রগুলি যুক্ত করে একটি "দ্রুত এবং নোংরা" সমাধানটি ব্যবহার করব এবং মিটারে এক্স এবং ওয়াই বেছে বেছে জ্যামিতির গণনা ক্লিক করুন। যদি এই বিকল্পটি বেছে নেওয়া সম্ভব না হয় তবে আপনার এমএক্সডি এর সমন্বিত সিস্টেমটি পরিবর্তন করুন। আমি এর আগে একটি প্রকল্পে কাজ করছিলাম, যেখানে আমার ক্লায়েন্ট দীর্ঘ / ল্যাট, এক্স / ওয়াই এবং গাউস-ক্রুয়েজার আর / এইচ প্রতিটি আকারের ফাইলে সমস্ত মান পছন্দ করে। জটিল গণনা এড়ানোর জন্য, কেবলমাত্র অনুমানগুলি পরিবর্তন করা এবং জ্যামিতির গণনা করা এটি সবচেয়ে কার্যকর উপায় ছিল।
Basto

0

আপনার যদি উচ্চ-নির্ভুলতা এবং জোরালো জিওডেসিক পরিমাপের প্রয়োজন হয় তবে জিওগ্রাফিকলিব ব্যবহার করুন , যা সি ++, জাভা, এমএটিএলবি, পাইথন ইত্যাদি সহ বেশ কয়েকটি প্রোগ্রামিং ভাষায় লিখিত is

দেখুন CFF Karney (2013) "geodesics জন্য আলগোরিদিম" একটি সাহিত্য রেফারেন্সের জন্য। নোট করুন যে এই অ্যালগোরিদমগুলি ভিন্স্টির অ্যালগরিদমের চেয়ে বেশি শক্তিশালী এবং নির্ভুল, উদাহরণস্বরূপ অ্যান্টিপোডগুলির নিকটে।

দুটি পয়েন্টের মধ্যে মিটারে দূরত্ব গণনা করতে, বিপরীত জিওডেসিক দ্রবণs12 থেকে দূরত্বের বৈশিষ্ট্যটি পান । উদাহরণস্বরূপ, পাইথনের ভৌগলিক প্যাকেজ সহ

from geographiclib.geodesic import Geodesic
g = Geodesic.WGS84.Inverse(-41.32, 174.81, 40.96, -5.50)
print(g)  # shows:
{'a12': 179.6197069334283,
 'azi1': 161.06766998615873,
 'azi2': 18.825195123248484,
 'lat1': -41.32,
 'lat2': 40.96,
 'lon1': 174.81,
 'lon2': -5.5,
 's12': 19959679.26735382}

বা একটি সুবিধাজনক ফাংশন তৈরি করুন যা মিটার থেকে কিলোমিটারে রূপান্তর করে:

dist_km = lambda a, b: Geodesic.WGS84.Inverse(a[0], a[1], b[0], b[1])['s12'] / 1000.0
a = (-41.32, 174.81)
b = (40.96, -5.50)
print(dist_km(a, b))  # 19959.6792674 km

এখন তালিকাগুলির মধ্যে Aএবং B100 টি পয়েন্ট সহ প্রতিটিের মধ্যে নিকটতম স্থানটি সন্ধান করতে :

from random import uniform
from itertools import product
A = [(uniform(-90, 90), uniform(-180, 180)) for x in range(100)]
B = [(uniform(-90, 90), uniform(-180, 180)) for x in range(100)]
a_min = b_min = min_dist = None
for a, b in product(A, B):
    d = dist_km(a, b)
    if min_dist is None or d < min_dist:
        min_dist = d
        a_min = a
        b_min = b

print('%.3f km between %s and %s' % (min_dist, a_min, b_min))

22.481 কিমি (84.57916462672875, 158.67545706102192) এবং (84.70326937581333, 156.9784597422855) এর মধ্যে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.