最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Zoom and position management in MapKit.js - Stack Overflow

programmeradmin4浏览0评论

I've created the following map using MapKit.js, with hundred of custom annotations, clustering (yellow dots) and callout popup on annotation click.

What I want to do, when clicking on the popup link, is simply to zoom in one step and center view on the clicked annotation (in a responsive context).

In Google Maps, that I'm used to, you simply position the map by its center and zoom level.

In MapKit.js, you use a center/region bo, and honestly I can't understand how this works.

This center/region thing still doesn't make sense to me, so I've decided to override MapKit.js with a zoom feature.

Thanks to this post, I've manage to implement the zoom calculation, which seems to be ok.

I need now to implement the set zoom action.
No success yet, this math things are so far now ^^

Function:

function MapKitJsZoom(map) {
    var LN2 = 0.6931471805599453; // ???
    var WH = 256; // World Height
    var WW = 256; // World Width
    var MAX = 21; // Max zoom level

    // GET CURRENT ZOOM.

    var latToRad = function (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;
    };

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

    this.get = function () {
        var bounds = map.region.toBoundingRegion();
        var latFraction = (latToRad(bounds.northLatitude) - latToRad(bounds.southLatitude)) / Math.PI;
        var latZoom = zoom(map.element.clientHeight, WH, latFraction);

        var lngDiff = bounds.eastLongitude - bounds.westLongitude;
        var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
        var lngZoom = zoom(map.element.clientWidth, WW, lngFraction);

        return Math.round(Math.min(latZoom, lngZoom, MAX));
    };

    // SET CURRENT ZOOM

    this.set = function (zoom) {
        // TODO
        // I need to calculate latitude and longitude deltas
        // that correspond to required zoom based on viewport size
        // (map.element.clientWidth and map.element.clientHeight)

        map.region.span = new mapkit.CoordinateSpan(latitudeDelta, longitudeDelta);
    };

}

Usage:

    var map = new mapkit.Map("map");

    map.zoom = new MapKitJsZoom(map);

    map.addEventListener('region-change-end', function () {
        console.log(map.zoom.get());
    });

I've created the following map using MapKit.js, with hundred of custom annotations, clustering (yellow dots) and callout popup on annotation click.

What I want to do, when clicking on the popup link, is simply to zoom in one step and center view on the clicked annotation (in a responsive context).

In Google Maps, that I'm used to, you simply position the map by its center and zoom level.

In MapKit.js, you use a center/region bo, and honestly I can't understand how this works.

This center/region thing still doesn't make sense to me, so I've decided to override MapKit.js with a zoom feature.

Thanks to this post, I've manage to implement the zoom calculation, which seems to be ok.

I need now to implement the set zoom action.
No success yet, this math things are so far now ^^

Function:

function MapKitJsZoom(map) {
    var LN2 = 0.6931471805599453; // ???
    var WH = 256; // World Height
    var WW = 256; // World Width
    var MAX = 21; // Max zoom level

    // GET CURRENT ZOOM.

    var latToRad = function (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;
    };

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

    this.get = function () {
        var bounds = map.region.toBoundingRegion();
        var latFraction = (latToRad(bounds.northLatitude) - latToRad(bounds.southLatitude)) / Math.PI;
        var latZoom = zoom(map.element.clientHeight, WH, latFraction);

        var lngDiff = bounds.eastLongitude - bounds.westLongitude;
        var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
        var lngZoom = zoom(map.element.clientWidth, WW, lngFraction);

        return Math.round(Math.min(latZoom, lngZoom, MAX));
    };

    // SET CURRENT ZOOM

    this.set = function (zoom) {
        // TODO
        // I need to calculate latitude and longitude deltas
        // that correspond to required zoom based on viewport size
        // (map.element.clientWidth and map.element.clientHeight)

        map.region.span = new mapkit.CoordinateSpan(latitudeDelta, longitudeDelta);
    };

}

Usage:

    var map = new mapkit.Map("map");

    map.zoom = new MapKitJsZoom(map);

    map.addEventListener('region-change-end', function () {
        console.log(map.zoom.get());
    });
Share Improve this question edited Dec 11, 2024 at 7:38 yivi 47.7k18 gold badges130 silver badges155 bronze badges asked Jun 5, 2019 at 8:45 bgazebgaze 1,0101 gold badge10 silver badges25 bronze badges 1
  • Apparently, LN2 is the natural logarithm of 2, and is available in js via Math.LN2: developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – majman Commented Jan 24, 2020 at 20:56
Add a ment  | 

1 Answer 1

Reset to default 8

There are two methods of acplishing this:

1) set center then change zoom level

var newCenter = new mapkit.Coordinate(37.792446, -122.399360);
map._impl.zoomLevel--;
map.setCenterAnimated(newCenter, true);

2) set region using center and span (delta in degress)

var newCenter = new mapkit.Coordinate(37.792446, -122.399360);
var span = new mapkit.CoordinateSpan(.01);
var region = new mapkit.CoordinateRegion(newCenter, span);
map.setRegionAnimated(region)
发布评论

评论列表(0)

  1. 暂无评论