আমি কীভাবে ওয়ার্ডপ্রেসে কোনও অবস্থান ভিত্তিক (পিন কোড) অনুসন্ধান প্রয়োগ করতে পারি?


19

আমি একটি স্থানীয় ব্যবসায়িক ডিরেক্টরি সাইটে কাজ করছি যা ব্যবসায়িক প্রবেশের জন্য কাস্টম পোস্ট ধরণের ব্যবহার করবে। ক্ষেত্রগুলির মধ্যে একটি হবে "জিপ কোড"। আমি কীভাবে একটি অবস্থান ভিত্তিক অনুসন্ধান সেট আপ করতে পারি?

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


2
আমি একটি অনুগ্রহ শুরু করছি কারণ এটি একটি আকর্ষণীয় এবং চ্যালেঞ্জিং প্রশ্ন। আমার নিজের নিজস্ব কয়েকটি ধারণা রয়েছে ... তবে আমি দেখতে চাই যে আরও কিছু মার্জিত (এবং আরও সহজভাবে নির্মাণের) সাথে কেউ আসতে পারে কিনা।
EAMAN

ধন্যবাদ ইমন এটি সাহায্য করতে পারে: briancray.com/2009/04/01/…
matt

আমার কাছে কেবল এখানে
পরামর্শটি হ'ল শুঁটির

@ নেটকন্সট্রাক্টর ডট কম - আমি এর জন্য পডগুলি প্রস্তাব করব না; কাস্টম পোস্ট ধরণের বনাম পডস এই সমস্যাটি সরবরাহ করে আসলেই কোনও লাভ নেই।
মাইকচিন্কেল

@ ম্যাট : সাইটটি এখনও চূড়ান্ত হয়নি বা মোতায়েন করা হয়নি যদিও আমি সম্প্রতি এর সাথে সাদৃশ্যপূর্ণ কিছু বাস্তবায়ন করেছি। আসলে এটি বেশ কিছুটা আছে। আমি এটিকে কোনও পর্যায়ে একটি স্টোর লোকেটার প্লাগইন হিসাবে প্যাকেজ করার পরিকল্পনা করি তবে এটি এখনও সাধারণ সমাধান হিসাবে পোস্ট করতে পারি এমন কিছু নয়। অফলাইনে আমার সাথে যোগাযোগ করুন এবং আপনি যদি প্রয়োজনীয় উত্তরটি না পান তবে আমি সহায়তা করতে পারি।
মাইকচিন্কেল

উত্তর:


10

আমি গ্যাব্রিয়েলক এবং লিঙ্কযুক্ত ব্লগ পোস্টের উত্তরটি ডাটাবেস সূচকগুলি ব্যবহার করে এবং প্রকৃত দূরত্ব গণনার সংখ্যাকে হ্রাস করে সংশোধন করব

যদি আপনি ব্যবহারকারীর স্থানাঙ্কগুলি জানেন এবং আপনি সর্বাধিক দূরত্বটি (10 কিলোমিটার বলুন) জানেন তবে আপনি মাঝের বর্তমান অবস্থানের সাথে 20 কিলোমিটার অবধি 20 কিমি দৈর্ঘ্যের একটি বক্স আঁকতে পারেন। এই সীমাবদ্ধ স্থানাঙ্ক এবং কেবলমাত্র এই অক্ষাংশ এবং দ্রাঘিমাংশের মধ্যে অনুসন্ধান করুন । আপনার ডাটাবেস ক্যোয়ারিতে এখনও ত্রিকোণমিতি ফাংশন ব্যবহার করবেন না, কারণ এটি সূচকগুলি ব্যবহার হতে বাধা দেবে। (সুতরাং আপনি যদি বাউন্ডিং বাক্সের উত্তর-পূর্ব কোণে থাকেন তবে আপনার কাছ থেকে 12 কিলোমিটার দূরের কোনও স্টোর আপনি পেতে পারেন, তবে আমরা এটি পরবর্তী ধাপে ফেলে দেব))

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

সম্পর্কিত অনুসন্ধানের জন্য ( "দশটি নিকটস্থ স্টোর দিন") ) আপনি একই ধরণের অনুসন্ধান করতে পারেন তবে প্রাথমিক দূরত্ব অনুমানের সাথে (তাই আপনি 10 কিলোমিটার এলাকা দিয়ে 10 কিলোমিটার এলাকা দিয়ে শুরু করেন, এবং আপনার কাছে পর্যাপ্ত স্টোর না থাকলে আপনি এটিকে প্রসারিত করুন) 20 কিমি বাই 20 কিমি এবং আরও কিছু)। এই প্রাথমিক দূরত্ব অনুমানের জন্য আপনি একবার মোট ক্ষেত্রের উপরে স্টোরের সংখ্যা গণনা করুন এবং এটি ব্যবহার করুন। অথবা প্রয়োজনীয় প্রশ্নের সংখ্যা লগ করুন এবং সময়ের সাথে মানিয়ে নিন।

আমি মাইকের সম্পর্কিত প্রশ্নে একটি পূর্ণ কোড উদাহরণ যুক্ত করেছি , এবং এখানে একটি এক্সটেনশন যা আপনাকে নিকটতম এক্স অবস্থান দেয় (দ্রুত এবং সবেমাত্র পরীক্ষিত):

class Monkeyman_Geo_ClosestX extends Monkeyman_Geo
{
    public static $closestXStartDistanceKm = 10;
    public static $closestXMaxDistanceKm = 1000; // Don't search beyond this

    public function addAdminPages()
    {
        parent::addAdminPages();
        add_management_page( 'Location closest test', 'Location closest test', 'edit_posts', __FILE__ . 'closesttest', array(&$this, 'doClosestTestPage'));
    }

    public function doClosestTestPage()
    {
        if (!array_key_exists('search', $_REQUEST)) {
            $default_lat = ini_get('date.default_latitude');
            $default_lon = ini_get('date.default_longitude');

            echo <<<EOF
<form action="" method="post">
    <p>Number of posts: <input size="5" name="post_count" value="10"/></p>
    <p>Center latitude: <input size="10" name="center_lat" value="{$default_lat}"/>
        <br/>Center longitude: <input size="10" name="center_lon" value="{$default_lon}"/></p>
    <p><input type="submit" name="search" value="Search!"/></p>
</form>
EOF;
            return;
        }
        $post_count = intval($_REQUEST['post_count']);
        $center_lon = floatval($_REQUEST['center_lon']);
        $center_lat = floatval($_REQUEST['center_lat']);

        var_dump(self::getClosestXPosts($center_lon, $center_lat, $post_count));
    }

    /**
     * Get the closest X posts to a given location
     *
     * This might return more than X results, and never more than
     * self::$closestXMaxDistanceKm away (to prevent endless searching)
     * The results are sorted by distance
     *
     * The algorithm starts with all locations no further than
     * self::$closestXStartDistanceKm, and then grows this area
     * (by doubling the distance) until enough matches are found.
     *
     * The number of expensive calculations should be minimized.
     */
    public static function getClosestXPosts($center_lon, $center_lat, $post_count)
    {
        $search_distance = self::$closestXStartDistanceKm;
        $close_posts = array();
        while (count($close_posts) < $post_count && $search_distance < self::$closestXMaxDistanceKm) {
            list($north_lat, $east_lon, $south_lat, $west_lon) = self::getBoundingBox($center_lat, $center_lon, $search_distance);

            $geo_posts = self::getPostsInBoundingBox($north_lat, $east_lon, $south_lat, $west_lon);


            foreach ($geo_posts as $geo_post) {
                if (array_key_exists($geo_post->post_id, $close_posts)) {
                    continue;
                }
                $post_lat = floatval($geo_post->lat);
                $post_lon = floatval($geo_post->lon);
                $post_distance = self::calculateDistanceKm($center_lat, $center_lon, $post_lat, $post_lon);
                if ($post_distance < $search_distance) {
                    // Only include those that are in the the circle radius, not bounding box, otherwise we might miss some closer in the next step
                    $close_posts[$geo_post->post_id] = $post_distance;
                }
            }

            $search_distance *= 2;
        }

        asort($close_posts);

        return $close_posts;
    }

}

$monkeyman_Geo_ClosestX_instace = new Monkeyman_Geo_ClosestX();

8

প্রথমে আপনার এমন একটি টেবিলের দরকার যা দেখতে এমন কিছু দেখাচ্ছে:

zip_code    lat     lon
10001       40.77    73.98

... প্রতিটি জিপ কোডের জন্য পপুলেটেড। আপনি যদি সেভাবে সন্ধান করতে চান তবে শহর এবং রাজ্যের ক্ষেত্রগুলি যুক্ত করে আপনি এটিতে প্রসারিত করতে পারেন।

তারপরে প্রতিটি স্টোরকে একটি জিপ কোড দেওয়া যেতে পারে এবং যখন আপনাকে দূরত্ব গণনা করতে হবে তখন আপনি স্টোরের ডেটাতে ল্যাট / ল্যাব টেবিলটিতে যোগ দিতে পারেন।

তারপরে আপনি স্টোর এবং ব্যবহারকারীর জিপ কোডগুলির জন্য অক্ষাংশ এবং দ্রাঘিমাংশ পেতে সেই সারণিকে জিজ্ঞাসা করবেন। একবার আপনি এটি পেয়ে গেলে আপনি আপনার অ্যারেটি তৈরি করতে পারেন এবং এটি "দূরত্ব পান" ফাংশনে পাস করতে পারেন:

$user_location = array(
    'latitude' => 42.75,
    'longitude' => 73.80,
);

$output = array();
$results = $wpdb->get_results("SELECT id, zip_code, lat, lon FROM store_table");
foreach ( $results as $store ) {
    $store_location = array(
        'zip_code' => $store->zip_code, // 10001
        'latitude' => $store->lat, // 40.77
        'longitude' => $store->lon, // 73.98
    );

    $distance = get_distance($store_location, $user_location, 'miles');

    $output[$distance][$store->id] = $store_location;
}

ksort($output);

foreach ($output as $distance => $store) {
    foreach ( $store as $id => $location ) {
        echo 'Store ' . $id . ' is ' . $distance . ' away';
    }
}

function get_distance($store_location, $user_location, $units = 'miles') {
    if ( $store_location['longitude'] == $user_location['longitude'] &&
    $store_location['latitude'] == $user_location['latitude']){
        return 0;

    $theta = ($store_location['longitude'] - $user_location['longitude']);
    $distance = sin(deg2rad($store_location['latitude'])) * sin(deg2rad($user_location['latitude'])) + cos(deg2rad($store_location['latitude'])) * cos(deg2rad($user_location['latitude'])) * cos(deg2rad($theta));
    $distance = acos($distance);
    $distance = rad2deg($distance);
    $distance = $distance * 60 * 1.1515;

    if ( 'kilometers' == $units ) {
        $distance = $distance * 1.609344;
    }

    return round($distance);
}

এটি ধারণার একটি প্রমাণ হিসাবে বোঝানো হয়েছে, কোড নয় যা আমি আসলে বাস্তবায়নের পরামর্শ দেব। উদাহরণস্বরূপ, যদি আপনার 10,000 টি স্টোর থাকে তবে সেগুলি জিজ্ঞাসা করা এবং প্রতিটি অনুরোধের মাধ্যমে লুপ করা এবং সেগুলি সাজানোর জন্য এটি একটি দুর্দান্ত ব্যয়বহুল ক্রিয়াকলাপ হবে।


ফলাফলগুলি ক্যাশে করা যায়? এছাড়াও, জিপ কোডের ডাটাবেসগুলিতে কমরেটিকভাবে পাওয়া (বা যদি সেখানে একটি ফ্রি) থাকে তবে কোয়েরি করা কি সহজ হবে?
ম্যাট

1
@ ম্যাট - বাণিজ্যিকভাবে বা নিখরচায় কোনও একের কাছে ক্যোয়ারী বলতে কী বোঝ ? ক্যাচিং সর্বদা সম্ভব হওয়া উচিত, দেখুন কোডেক্স.ওয়ার্ডপ্রেস.আর.
ট্রান্সিয়েন্টস_এপিআই

@ হাক্রে: কিছু মনে নেই, আমি মনে করি আমি এখন আমার মাথার উপর দিয়ে কথা বলছি। আমি দূরত্ব পেতে একটি জিপ কোড ডাটাবেসগুলি (ইউএসপিএস, গুগল ম্যাপস ...) ব্যবহার করার কথা বলছি তবে আমি বুঝতে পারি নি যে তারা সম্ভবত দূরত্বগুলি সংরক্ষণ করে না, তারা কেবল জিপ কোড এবং স্থানাঙ্ক সঞ্চয় করে এবং এটি হবে এটি গণনা করতে আমার উপর আপ করুন।
ম্যাট

3

মাইএসকিউএল ডকুমেন্টেশনে স্থানিক এক্সটেনশনের তথ্যও অন্তর্ভুক্ত রয়েছে। অদ্ভুতভাবে, স্ট্যান্ডার্ড দূরত্ব () ফাংশনটি উপলভ্য নয় তবে এই পৃষ্ঠাটি দেখুন: http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html "রূপান্তর কীভাবে করবেন তার বিশদ জন্য দুটি পয়েন্ট একটি রেখার মান এবং তার দৈর্ঘ্য গণনা। "

নোট করুন যে প্রতিটি বিক্রেতারা একটি জিপ কোডের "সেন্ট্রয়েড" উপস্থাপনের জন্য বিভিন্ন অক্ষাংশ এবং দ্রাঘিমাংশ সরবরাহ করতে পারে Note এটি সত্যিকারের সংজ্ঞায়িত জিপ কোড "বাউন্ডারি" ফাইল নেই তা জেনে রাখাও মূল্যবান। প্রতিটি বিক্রেতার নিজস্ব সীমানা থাকবে যা ইউএসপিএস জিপ কোড তৈরি করে এমন ঠিকানাগুলির নির্দিষ্ট তালিকার সাথে মোটামুটি মেলে। (উদাহরণস্বরূপ, কিছু "সীমানা" এ ক্ষেত্রে আপনাকে রাস্তার উভয় দিক অন্তর্ভুক্ত করতে হবে, অন্যদের মধ্যে কেবল একটির জন্য)) বিক্রেতাদের দ্বারা বহুল ব্যবহৃত জিপ কোড ট্যাবুলেশন অঞ্চলগুলি (জেডসিটিএ), "অবশ্যই জিপ কোড সরবরাহের ক্ষেত্রগুলি চিত্রিত করবেন না, এবং মেল বিতরণের জন্য ব্যবহৃত সমস্ত জিপ কোডগুলি অন্তর্ভুক্ত করবেন না " http://www.census.gov/geo/www/cob/zt_metadata.html

অনেকটা ডাউনটাউন ব্যবসায়ের নিজস্ব জিপ কোড থাকবে have আপনি যতটা সম্ভব ডেটাসেটটি সম্পূর্ণ করতে চাইবেন, তাই আপনি পিনকোডের একটি তালিকা পেয়েছেন যাতে "পয়েন্ট" জিপ কোড (সাধারণত ব্যবসা) এবং "সীমানা" জিপ কোড উভয়ই সন্ধান করে তা নিশ্চিত হয়ে নিন।

Http://www.semaphorecorp.com/ থেকে জিপকোড ডেটা নিয়ে কাজ করার অভিজ্ঞতা আমার আছে । এমনকি এটি 100% সঠিক ছিল না। উদাহরণস্বরূপ, যখন আমার ক্যাম্পাসটি একটি নতুন মেইলিং ঠিকানা এবং নতুন জিপ কোড নিয়েছে তখন জিপটি ভুলভাবে স্থাপন করা হয়েছিল। এটি বলেছিল, এটি কেবলমাত্র একমাত্র ডেটা উত্সই আমি খুঁজে পেলাম যে এমনকি নতুন জিপ কোডটি তৈরি করার পরে খুব শীঘ্রই এটি ছিল।

আপনার অনুরোধটি কীভাবে মেটানো যায় তার জন্য আমার বইতে একটি রেসিপি ছিল ... দ্রুপালে। এটি গুগল ম্যাপস সরঞ্জাম মডিউল ( http://drupal.org/project/gmaps , একটি http://drupal.org/project/gmap , এছাড়াও একটি উপযুক্ত মডিউল সঙ্গে বিভ্রান্ত না করার উপর নির্ভর করে ) আপনি কিছু সহায়ক নমুনা খুঁজে পেতে পারেন You এই মডিউলগুলিতে কোড, অবশ্যই, তারা ওয়ার্ডপ্রেসের বাক্সের বাইরে কাজ করবে না।

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