গুগল ম্যাপস ভি 3 - প্রদত্ত সীমাগুলির জন্য জুম স্তর কীভাবে গণনা করা যায়


138

আমি গুগল ম্যাপস ভি 3 এপিআই ব্যবহার করে প্রদত্ত গণ্ডির জন্য জুম স্তরের গণনা করার একটি উপায় খুঁজছি, getBoundsZoomLevel()ভি 2 এপিআইয়ের মতো।

আমি যা করতে চাই তা এখানে:

// These are exact bounds previously captured from the map object
var sw = new google.maps.LatLng(42.763479, -84.338918);
var ne = new google.maps.LatLng(42.679488, -84.524313);
var bounds = new google.maps.LatLngBounds(sw, ne);
var zoom = // do some magic to calculate the zoom level

// Set the map to these exact bounds
map.setCenter(bounds.getCenter());
map.setZoom(zoom);

// NOTE: fitBounds() will not work

দুর্ভাগ্যক্রমে, আমি fitBounds()আমার বিশেষ ব্যবহারের ক্ষেত্রে পদ্ধতিটি ব্যবহার করতে পারি না । এটি মানচিত্রে চিহ্নিতকারীদের ফিটিংয়ের জন্য ভাল কাজ করে তবে সঠিক সীমা নির্ধারণের জন্য এটি ভাল কাজ করে না। কেন আমি fitBounds()পদ্ধতিটি ব্যবহার করতে পারি না তার একটি উদাহরণ এখানে ।

map.fitBounds(map.getBounds()); // not what you expect

4
শেষ উদাহরণটি দুর্দান্ত এবং অত্যন্ত চিত্রণার্থ! +1 টি। আমি একই সমস্যা
টিএমএস

দুঃখিত, সংযুক্ত ভুল প্রশ্ন, এটি সঠিক লিঙ্ক
টিএমএস

এই প্রশ্নটি অন্য প্রশ্নের সদৃশ নয় । অন্য প্রশ্নের উত্তরটি ব্যবহার করা fitBounds()। এই প্রশ্নটি fitBounds()অপর্যাপ্ত হলে কী করণীয় তা জিজ্ঞাসা করে - এটি জুমের উপর নির্ভর করে বা আপনি জুম করতে চান না (যেমন, আপনি কেবল জুম স্তরটি চান)।
জন এস

@ নিক ক্লার্ক: আপনি কীভাবে জানবেন যে ডাব্লু, নে বাউন্ডারি সেট করা হবে? এর আগে আপনি কীভাবে তাদের ধরে ফেললেন?
বর্ধপ্রকাশ

উত্তর:


108

গুগল গ্রুপে অনুরূপ প্রশ্ন জিজ্ঞাসা করা হয়েছে: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892

প্রতিটি পদক্ষেপে স্কেল দ্বিগুণ হওয়ার সাথে সাথে জুমের স্তরগুলি পৃথক। সুতরাং সাধারণভাবে আপনি ঠিক যে সীমানা চান তা ফিট করতে পারবেন না (যদি আপনি নির্দিষ্ট মানচিত্রের আকারের সাথে খুব ভাগ্যবান না হন)।

আরেকটি সমস্যা হ'ল পাশের দৈর্ঘ্যের মধ্যে অনুপাত উদাহরণস্বরূপ আপনি বর্গাকার মানচিত্রের অভ্যন্তরে পাতলা আয়তক্ষেত্রের সাথে সঠিকভাবে সীমানা ফিট করতে পারবেন না।

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

আপনার যদি জুমটি সঞ্চয় করার পরিবর্তে সত্যিকারের জুম গণনা করতে হয় তবে এই কৌশলটি করা উচিত:

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

var GLOBE_WIDTH = 256; // a constant in Google's map projection
var west = sw.lng();
var east = ne.lng();
var angle = east - west;
if (angle < 0) {
  angle += 360;
}
var zoom = Math.round(Math.log(pixelWidth * 360 / angle / GLOBE_WIDTH) / Math.LN2);

1
আপনি কি ল্যাটের জন্য এটি পুনরাবৃত্তি করতে হবে না এবং তারপরে 2 এর ফলাফলের মিনিটটি বেছে নেবেন? আমি মনে করি না যে এটি একটি দীর্ঘ সংকীর্ণ সীমার জন্য কাজ করবে .....
হোয়াইটটম

3
ম্যাথ.গ্রাউন্ডে ম্যাথ.ফ্লোয়ারে পরিবর্তন নিয়ে আমার পক্ষে দুর্দান্ত কাজ করে। অসংখ্য ধন্যবাদ.
পিট

3
এটি অক্ষাংশকে বিবেচনায় না নিলে কীভাবে সঠিক হতে পারে? নিরক্ষীয় অঞ্চলের কাছাকাছি এটি সূক্ষ্ম হওয়া উচিত তবে প্রদত্ত জুম স্তরের মানচিত্রের স্কেল অক্ষাংশের উপর নির্ভর করে পরিবর্তিত হবে!
ইয়াল

1
@ পিট ভাল পয়েন্ট, সাধারণভাবে আপনি সম্ভবত জুম স্তরটি গোল করতে চান যাতে আপনি মানচিত্রের চেয়ে কিছুটা কম চেয়ে বরং কিছুটা বেশি ফিট করতে পারেন। আমি ম্যাথ.গ্রাউন্ড ব্যবহার করেছি কারণ ওপির পরিস্থিতিতে রাউন্ডিংয়ের আগে মানটি প্রায় অবিচ্ছেদ্য হওয়া উচিত।
গিলস গার্ডাম

20
পিক্সেলউথের মান কী
আলবার্ট জাগানি

279

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

এখানে একটি ফাংশন যা অক্ষাংশ এবং দ্রাঘিমাংশ উভয়ই ব্যবহার করে:

function getBoundsZoomLevel(bounds, mapDim) {
    var WORLD_DIM = { height: 256, width: 256 };
    var ZOOM_MAX = 21;

    function latRad(lat) {
        var sin = Math.sin(lat * Math.PI / 180);
        var radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
        return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
    }

    function zoom(mapPx, worldPx, fraction) {
        return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
    }

    var ne = bounds.getNorthEast();
    var sw = bounds.getSouthWest();

    var latFraction = (latRad(ne.lat()) - latRad(sw.lat())) / Math.PI;

    var lngDiff = ne.lng() - sw.lng();
    var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;

    var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
    var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);

    return Math.min(latZoom, lngZoom, ZOOM_MAX);
}

Demo on jsfiddle

পরামিতি:

"সীমানা" প্যারামিটার মান একটি google.maps.LatLngBoundsবস্তু হওয়া উচিত ।

"ম্যাপডিম" পরামিতি মানটি "উচ্চতা" এবং "প্রস্থ" বৈশিষ্ট্যযুক্ত একটি বস্তু হওয়া উচিত যা মানচিত্রটি প্রদর্শন করে এমন ডিওএম উপাদানটির উচ্চতা এবং প্রস্থকে উপস্থাপন করে। আপনি প্যাডিং নিশ্চিত করতে চাইলে আপনি এই মানগুলি হ্রাস করতে চাইতে পারেন। এটি হ'ল আপনি চাইবেন না যে সীমান্তের মধ্যে মানচিত্রের চিহ্নিতকারীগুলি মানচিত্রের প্রান্তের খুব কাছাকাছি থাকুক।

আপনি jQuery লাইব্রেরি ব্যবহার করছেন, mapDimমান নিম্নলিখিত হিসাবে প্রাপ্ত করা যেতে পারে:

var $mapDiv = $('#mapElementId');
var mapDim = { height: $mapDiv.height(), width: $mapDiv.width() };

আপনি যদি প্রোটোটাইপ লাইব্রেরি ব্যবহার করেন তবে ম্যাপডিম মানটি নীচের হিসাবে পাওয়া যাবে:

var mapDim = $('mapElementId').getDimensions();

ফেরত মূল্য:

রিটার্ন মান হ'ল সর্বাধিক জুম স্তর যা এখনও সম্পূর্ণ সীমা প্রদর্শন করবে। এই মানটি 0অন্তর্ভুক্ত সহ সর্বোচ্চ জুম স্তরের মধ্যে হবে।

সর্বাধিক জুম স্তরটি 21. (আমি বিশ্বাস করি এটি গুগল ম্যাপস এপিআই v2 এর জন্য মাত্র 19


ব্যাখ্যা:

গুগল মানচিত্র একটি মার্কেটর প্রক্ষেপণ ব্যবহার করে। একটি মার্কেটর প্রক্ষেপণে দ্রাঘিমাংশের রেখাগুলি সমানভাবে ব্যবধানযুক্ত, তবে অক্ষাংশের রেখাগুলি নয়। নিরক্ষীয় रेखा থেকে মেরুতে যাওয়ার সময় অক্ষাংশের রেখার মধ্যকার দূরত্ব বৃদ্ধি পায়। মেরুতে পৌঁছানোর সাথে সাথে দূরত্বটি অনন্তের দিকে ঝুঁকছে। গুগল মানচিত্রের মানচিত্রটি, প্রায় 85 ডিগ্রি উত্তর বা প্রায় -85 ডিগ্রি দক্ষিণের নীচে অক্ষাংশ প্রদর্শন করে না। ( রেফারেন্স ) (আমি +/- 85.05112877980658 ডিগ্রিতে প্রকৃত কাটফোন গণনা করি))

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

অন্যান্য নোট:

  1. জুম স্তরগুলি সর্বোচ্চ জুম স্তর থেকে শুরু করে। জুম স্তর 0 হ'ল মানচিত্রটি পুরোপুরি জুম আউট। উচ্চতর স্তরগুলি আরও মানচিত্র জুম করে। ( রেফারেন্স )
  2. জুম স্তর 0 এ পুরো পৃথিবী এমন একটি অঞ্চলে প্রদর্শিত হতে পারে যা 256 x 256 পিক্সেল। ( রেফারেন্স )
  3. প্রতিটি উচ্চতর জুম স্তরের জন্য একই ক্ষেত্রের প্রস্থ এবং উচ্চতা উভয়কে দ্বিগুণ করে একই ক্ষেত্রটি প্রদর্শন করতে প্রয়োজনীয় পিক্সেলের সংখ্যা। ( রেফারেন্স )
  4. মানচিত্রগুলি দ্রাঘিমাংশীয় দিকের মোড়কে, তবে অক্ষাংশীয় পথে নয়।

6
উত্তম উত্তর, এটি সর্বোচ্চ ভোট হওয়া উচিত কারণ এটি দ্রাঘিমাংশ এবং অক্ষাংশ উভয়রই হয়ে থাকে। এখন পর্যন্ত নিখুঁতভাবে কাজ করেছেন।
পিটার উস্টার

1
@ জন এস - এটি একটি দুর্দান্ত সমাধান এবং আমি আমার কাছে উপলব্ধ নেটিভ গুগল ম্যাপস ফিটবাউন্ড পদ্ধতিতে এটি ব্যবহার করার বিষয়ে ভাবনা করছি। আমি লক্ষ্য করেছি ফিটবাউন্ডগুলি কখনও কখনও এক জুম লেভেল ব্যাক হয় (জুম আউট), তবে আমি ধরে নিই যে এটি প্যাডিং যুক্ত করছে from এই এবং ফিটবাউন্ডস পদ্ধতির মধ্যে কেবল তখনই কেবল পার্থক্য, আপনি যে পরিমাণ প্যাডিং যুক্ত করতে চান তা উভয়ের মধ্যে জুম স্তরের পরিবর্তনের জন্য কোন অ্যাকাউন্ট?
জনহিতুর

1
@ জোহানট্রেনিয়র - সুবিধা # 1: আপনি এমনকি মানচিত্র তৈরির আগে এই পদ্ধতিটি ব্যবহার করতে পারেন, যাতে আপনি এর ফলাফলটি প্রাথমিক মানচিত্রের সেটিংসে সরবরাহ করতে পারেন। এর সাথে fitBounds, আপনাকে মানচিত্র তৈরি করতে হবে এবং তারপরে "সীমানা_চেনা" ইভেন্টটির জন্য অপেক্ষা করতে হবে।
জন এস

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

1
@ কার্লমিয়ার - আমি আমার উত্তরে এটি উল্লেখ করি না, তবে উপরে একটি মন্তব্যে আমি বলেছি যে এই ফাংশনটির একটি সুবিধা হ'ল আপনি এমনকি মানচিত্র তৈরির আগে এই পদ্ধতিটি ব্যবহার করতে পারেন। ব্যবহার করা map.getProjection()কিছু গণিত (এবং অভিক্ষেপ সম্পর্কে ধারণা) দূর করে দেবে, তবে এর অর্থ হবে মানচিত্রটি তৈরি না হওয়া এবং "প্রজেকশন_-পরিবর্তিত" ইভেন্টটি চালিত না হওয়া পর্যন্ত ফাংশনটি ডাকা যাবে না।
জন এস

39

এপিআই এর 3 সংস্করণ জন্য, এটি সহজ এবং কার্যকরী:

var latlngList = [];
latlngList.push(new google.maps.LatLng(lat, lng));

var bounds = new google.maps.LatLngBounds();
latlngList.each(function(n) {
    bounds.extend(n);
});

map.setCenter(bounds.getCenter()); //or use custom center
map.fitBounds(bounds);

এবং কিছু alচ্ছিক কৌশল:

//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom() - 1); 

// set a minimum zoom 
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom() > 15){
    map.setZoom(15);
}

1
মানচিত্রের সূচনা করার সময় কেন সর্বনিম্ন জুম স্তর নির্ধারণ করবেন না, যেমন: var mapOptions = {সর্বোচ্চ জুম: 15,};
কুশ

2
@ কুশ, ভাল পয়েন্ট তবে maxZoomব্যবহারকারীকে ম্যানুয়াল জুম করা থেকে বিরত রাখবে । আমার উদাহরণটি কেবল ডিফল্টজুম পরিবর্তন করে এবং কেবল এটির প্রয়োজন হলে।
d.raev

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

অ্যানিমেশনটি কোথাও প্রশ্নে বা আমার উত্তরে আলোচনা করা হয়নি। বিষয়টিতে আপনার যদি দরকারী উদাহরণ থাকে তবে কেবল একটি গঠনমূলক উত্তর তৈরি করুন, উদাহরণ সহ এবং কখন এবং কখন এটি ব্যবহার করা যেতে পারে।
d.raev

কোনও কারণে ম্যাপ.ফিটবাউন্ডস () কল করার পরে সেটZoom () কল করার সময় গুগল ম্যাপ জুম করে না। (gmaps বর্তমানে v3.25 হয়)
কাশীরাজা

4

এখানে ফাংশনের একটি কোটলিন সংস্করণ:

fun getBoundsZoomLevel(bounds: LatLngBounds, mapDim: Size): Double {
        val WORLD_DIM = Size(256, 256)
        val ZOOM_MAX = 21.toDouble();

        fun latRad(lat: Double): Double {
            val sin = Math.sin(lat * Math.PI / 180);
            val radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
            return max(min(radX2, Math.PI), -Math.PI) /2
        }

        fun zoom(mapPx: Int, worldPx: Int, fraction: Double): Double {
            return floor(Math.log(mapPx / worldPx / fraction) / Math.log(2.0))
        }

        val ne = bounds.northeast;
        val sw = bounds.southwest;

        val latFraction = (latRad(ne.latitude) - latRad(sw.latitude)) / Math.PI;

        val lngDiff = ne.longitude - sw.longitude;
        val lngFraction = if (lngDiff < 0) { (lngDiff + 360) } else { (lngDiff / 360) }

        val latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
        val lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);

        return minOf(latZoom, lngZoom, ZOOM_MAX)
    }

1

ধন্যবাদ, এটি একটি পললাইন সঠিকভাবে প্রদর্শন করতে সবচেয়ে উপযুক্ত জুম ফ্যাক্টর সন্ধান করতে আমাকে অনেক সহায়তা করেছে। আমার যে পয়েন্টগুলি ট্র্যাক করতে হবে তার মধ্যে আমি সর্বাধিক এবং সর্বনিম্ন স্থানাঙ্কগুলি খুঁজে পাই এবং যদি পথটি খুব "উল্লম্ব" হয় তবে আমি কোডের কয়েকটি লাইন যুক্ত করেছি:

var GLOBE_WIDTH = 256; // a constant in Google's map projection
var west = <?php echo $minLng; ?>;
var east = <?php echo $maxLng; ?>;
*var north = <?php echo $maxLat; ?>;*
*var south = <?php echo $minLat; ?>;*
var angle = east - west;
if (angle < 0) {
    angle += 360;
}
*var angle2 = north - south;*
*if (angle2 > angle) angle = angle2;*
var zoomfactor = Math.round(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2);

আসলে, আদর্শ জুম ফ্যাক্টরটি জুমফ্যাক্টর -১।


আমি পছন্দ var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;। তবুও, খুব সহায়ক।
মোজোয়েন

1

যেহেতু অন্যান্য সমস্ত উত্তরগুলির মধ্যে আমার কাছে একের পর এক পরিস্থিতিতে বা মানচিত্রের (মানচিত্রের প্রস্থ / উচ্চতা, প্রস্থের প্রস্থ / উচ্চতা ইত্যাদি) সমস্যা রয়েছে বলে মনে হয়েছে আমি আমার উত্তরটি এখানে রেখেছি ...

এখানে একটি খুব দরকারী জাভাস্ক্রিপ্ট ফাইল ছিল: http://www.polyarc.us/adjust.js

আমি এটির ভিত্তি হিসাবে এটি ব্যবহার করেছি:

var com = com || {};
com.local = com.local || {};
com.local.gmaps3 = com.local.gmaps3 || {};

com.local.gmaps3.CoordinateUtils = new function() {

   var OFFSET = 268435456;
   var RADIUS = OFFSET / Math.PI;

   /**
    * Gets the minimum zoom level that entirely contains the Lat/Lon bounding rectangle given.
    *
    * @param {google.maps.LatLngBounds} boundary the Lat/Lon bounding rectangle to be contained
    * @param {number} mapWidth the width of the map in pixels
    * @param {number} mapHeight the height of the map in pixels
    * @return {number} the minimum zoom level that entirely contains the given Lat/Lon rectangle boundary
    */
   this.getMinimumZoomLevelContainingBounds = function ( boundary, mapWidth, mapHeight ) {
      var zoomIndependentSouthWestPoint = latLonToZoomLevelIndependentPoint( boundary.getSouthWest() );
      var zoomIndependentNorthEastPoint = latLonToZoomLevelIndependentPoint( boundary.getNorthEast() );
      var zoomIndependentNorthWestPoint = { x: zoomIndependentSouthWestPoint.x, y: zoomIndependentNorthEastPoint.y };
      var zoomIndependentSouthEastPoint = { x: zoomIndependentNorthEastPoint.x, y: zoomIndependentSouthWestPoint.y };
      var zoomLevelDependentSouthEast, zoomLevelDependentNorthWest, zoomLevelWidth, zoomLevelHeight;
      for( var zoom = 21; zoom >= 0; --zoom ) {
         zoomLevelDependentSouthEast = zoomLevelIndependentPointToMapCanvasPoint( zoomIndependentSouthEastPoint, zoom );
         zoomLevelDependentNorthWest = zoomLevelIndependentPointToMapCanvasPoint( zoomIndependentNorthWestPoint, zoom );
         zoomLevelWidth = zoomLevelDependentSouthEast.x - zoomLevelDependentNorthWest.x;
         zoomLevelHeight = zoomLevelDependentSouthEast.y - zoomLevelDependentNorthWest.y;
         if( zoomLevelWidth <= mapWidth && zoomLevelHeight <= mapHeight )
            return zoom;
      }
      return 0;
   };

   function latLonToZoomLevelIndependentPoint ( latLon ) {
      return { x: lonToX( latLon.lng() ), y: latToY( latLon.lat() ) };
   }

   function zoomLevelIndependentPointToMapCanvasPoint ( point, zoomLevel ) {
      return {
         x: zoomLevelIndependentCoordinateToMapCanvasCoordinate( point.x, zoomLevel ),
         y: zoomLevelIndependentCoordinateToMapCanvasCoordinate( point.y, zoomLevel )
      };
   }

   function zoomLevelIndependentCoordinateToMapCanvasCoordinate ( coordinate, zoomLevel ) {
      return coordinate >> ( 21 - zoomLevel );
   }

   function latToY ( lat ) {
      return OFFSET - RADIUS * Math.log( ( 1 + Math.sin( lat * Math.PI / 180 ) ) / ( 1 - Math.sin( lat * Math.PI / 180 ) ) ) / 2;
   }

   function lonToX ( lon ) {
      return OFFSET + RADIUS * lon * Math.PI / 180;
   }

};

আপনি অবশ্যই এটি পরিষ্কার করতে পারেন বা প্রয়োজনে এটিকে ছোট করতে পারেন, তবে আমি এটি বুঝতে আরও সহজ করার প্রয়াসে পরিবর্তনশীল নামগুলি দীর্ঘ রেখেছি long

আপনি যদি ভাবছেন যে অফফেসটি কোথা থেকে এসেছে তবে দৃশ্যত 268435456 জুম স্তরের 21 পিক্সেলগুলির মধ্যে পৃথিবীর পরিধি অর্ধেক হবে ( http://www.appelsiini.net/2008/11/intr Productions-to-marker-clustering-with-google এর সাথে -ম্যাপস )।


0

ভ্যালেরিও তার সমাধানটি প্রায় সঠিক, কিন্তু কিছু যৌক্তিক ভুল আছে।

firstণাত্মক দিকে 360 যোগ করার আগে আপনাকে প্রথমে ওয়েথর অ্যাঙ্গেল 2 টি কোণ থেকে বড় কিনা তা পরীক্ষা করতে হবে।

অন্যথায় আপনার সবসময় কোণ থেকে বড় মান থাকে

সুতরাং সঠিক সমাধানটি হ'ল:

var west = calculateMin(data.longitudes);
var east = calculateMax(data.longitudes);
var angle = east - west;
var north = calculateMax(data.latitudes);
var south = calculateMin(data.latitudes);
var angle2 = north - south;
var zoomfactor;
var delta = 0;
var horizontal = false;

if(angle2 > angle) {
    angle = angle2;
    delta = 3;
}

if (angle < 0) {
    angle += 360;
}

zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2) - 2 - delta;

ডেল্টা রয়েছে, কারণ আমার উচ্চতার চেয়ে প্রস্থ রয়েছে।


0

map.getBounds()ক্ষণিকের ক্রিয়াকলাপ নয়, সুতরাং আমি একই ধরণের ইভেন্ট হ্যান্ডলারটি ব্যবহার করি। কফিস্ক্রিপ্টে আমার উদাহরণ এখানে

@map.fitBounds(@bounds)
google.maps.event.addListenerOnce @map, 'bounds_changed', =>
  @map.setZoom(12) if @map.getZoom() > 12

0

রিগ্যাক্ট-গুগল-ম্যাপের সাথে গড় ডিফল্ট সেন্টার খুঁজে পেতে কাজের উদাহরণ ES6:

const bounds = new google.maps.LatLngBounds();
paths.map((latLng) => bounds.extend(new google.maps.LatLng(latLng)));
const defaultCenter = bounds.getCenter();
<GoogleMap
 defaultZoom={paths.length ? 12 : 4}
 defaultCenter={defaultCenter}
>
 <Marker position={{ lat, lng }} />
</GoogleMap>

0

জিলস গার্ডমের দ্রাঘিমাংশের জন্য জুম স্তরের গণনা আমার পক্ষে ভাল কাজ করে। আপনি যদি অক্ষাংশের জন্য জুম ফ্যাক্টরটি গণনা করতে চান তবে এটি একটি সহজ সমাধান যা কার্যকরভাবে কাজ করে:

double minLat = ...;
double maxLat = ...;
double midAngle = (maxLat+minLat)/2;
//alpha is the non-negative angle distance of alpha and beta to midangle
double alpha  = maxLat-midAngle;
//Projection screen is orthogonal to vector with angle midAngle
//portion of horizontal scale:
double yPortion = Math.sin(alpha*Math.pi/180) / 2;
double latZoom = Math.log(mapSize.height / GLOBE_WIDTH / yPortion) / Math.ln2;

//return min (max zoom) of both zoom levels
double zoom = Math.min(lngZoom, latZoom);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.