自定义地图图块叠加问题 [英] Custom Map Tile Overlay Issues

查看:190
本文介绍了自定义地图图块叠加问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要显示几百到超过由谷歌地图提供的标准的卫星图像大约1000名高分辨率的航拍照片。这些图像是地理上分散的,所以我决定实施瓷砖服务器作为一个通用的asp.net处理器(* ashx的文件)。我将立足于以下网址在谷歌的开发者网站上显示的地图上,我的问题描述:

I have a need to display a couple hundred to perhaps one thousand high resolution aerial photographs over the standard satellite imagery provided by Google maps. The images are geographically dispersed, so I decided to implement a tile server as a generic asp.net handler (*.ashx file). I will be basing my issue descriptions on the map shown on Google's developer site at the following URL:

https://developers.google.com/maps/documentation/javascript/examples/maptype-overlay

一切都更多或更少的工作,但我有以下两个问题:

Everything is more-or-less working, but I am having the following two issues:

1)选择卫星地图类型,悬停在该按钮后产生下拉一个叫做标签复选框。我怎么能另复选框添加到下拉名为航空照片,将触发我的/叠加了吗?请问我要硬,利用谷歌地图的实现细节code JQuery的黑客,我也可以做到这一点通过API?

1) After selecting the "Satellite" map type, hovering over that button produces a dropdown with a checkbox called "Labels". How can I add another checkbox to that dropdown titled "Aerial Photographs" that will toggle my overlay on/off? Will I have to hard-code JQuery hacks that utilize Google Maps implementation details, or can I accomplish this through the API?

2)我* .ashx的处理程序返回任一图像,或者一个状态204(无内容)如果指定的瓦片不存在。问题是,204的结果没有缓存,所以我每次缩小,早在相同的位置,我的服务器被重击的客户端应该已经知道不存在的所有瓷砖的时间。我没有看到它记录了瓷砖服务器将返回什么,这样的空瓦,因此客户端可以缓存的结果。我应该返回,如果有一个特定的位置没有地图图块?

2) My *.ashx handler returns either the image, or a status 204 (no content) if the specified tile does not exist. The issue is that the 204 results are not cached, so every time I zoom out and back in to the same location, my server gets re-hit for all the tiles that the client should already know don't exist. I failed to see it documented what a tile server should return for such an "empty" tile, so the client can cache the result. What should I return if there is no map tile for a specific location?

感谢。

推荐答案

由于缺乏针对这一问题,很显然,稀疏瓷砖服务器是一种罕见的做法。以下是对于这两个问题的解决方案(但哈克可能):

Given the lack of response to this question, it is clear that sparse tile servers are an uncommon practice. The following is the solution (however hacky it may be) for both problems:

1)如何添加一个复选框,在卫星下拉菜单切换我的地图图层?不幸的是,没有任何的支持的方式做到这一点,所以我想出了以下令人难以置信的哈​​克code:

1) How do I add a checkbox to the "Satellite" dropdown to toggle my map layer? Unfortunately, there is no supported way to do this, so I came up with the following INCREDIBLY hacky code:

// Create a function to select the "Labels" checkbox
var getLabelButton = function() {
    return $('.gm-style-mtc:last > div:last > div:last');
};

// Clone the "Labels" checkbox used to show/hide the hybrid map overlay
var labelBtn   = getLabelButton();
var labelClone = labelBtn.clone();

// Change the display and hover text for the new button
labelClone.prop('title', Localizer.GetString('CustomImagery.Description'));
labelClone.find('label').html(Localizer.GetString('CustomImagery.Name'));

// Highlight the button when the client hovers the mouse over it
var checkbox        = labelClone.children('span');
var prevBackColor   = labelClone.css('background-color');
var prevBorderColor = checkbox  .css('border-color');
labelClone.hover(function() {
    labelClone.css('background-color', '#EBEBEB');
    checkbox  .css('border-color'    , '#666');
}, function() {
    labelClone.css('background-color', prevBackColor);
    checkbox  .css('border-color'    , prevBorderColor);
});

// Set the checkmark image source to be the correct value, instead of transparent
var checkmark    = checkbox .children('div');
var checkmarkImg = checkmark.children('img');
checkmarkImg.attr('src', 'https://maps.gstatic.com/mapfiles/mv/imgs8.png');

// Attach the new checkbox after the Labels checkbox
labelBtn.after(labelClone);

// Create a method to determine if the selected map type supports custom imagery
var mapTypesSupportingCustomImagery = [
    google.maps.MapTypeId.SATELLITE,
    google.maps.MapTypeId.HYBRID
];
var isImagerySupportedOnSelectedMapType = function() {
    var mapTypeId = googleMap.getMapTypeId();
    return (0 <= mapTypesSupportingCustomImagery.indexOf(mapTypeId));
};

// Show the checkmark and imagery if the initial map type supports it
if (isImagerySupportedOnSelectedMapType()) {
    checkmark.css('display', '');
    googleMap.overlayMapTypes.push(tileServer);
}

// Show/hide the checkmark and imagery when the user clicks on the checkbox
labelClone.on('click', function() {
    var showImagery = (checkmark.css('display') === 'none');
    if (showImagery) {
        checkmark.css('display', '');
        googleMap.overlayMapTypes.push(tileServer);
    } else {
        checkmark.css('display', 'none');
        var tileServerIndex = googleMap.overlayMapTypes.indexOf(tileServer);
        googleMap.overlayMapTypes.removeAt(tileServerIndex);
    }
});

// Create a function that returns whether the custom imagery should be displayed
var displayCustomImagery = function() {
    return (isImagerySupportedOnSelectedMapType() && checkmark.css('display') != 'none');
};

// Add an event listener to add the tile server when displaying satellite view
google.maps.event.addListener(googleMap, 'maptypeid_changed', function() {
    var tileServerIndex = googleMap.overlayMapTypes.indexOf(tileServer);
    if (displayCustomImagery()) {
        if (tileServerIndex < 0) {
            googleMap.overlayMapTypes.push(tileServer);
        }
    } else if (0 <= tileServerIndex) {
        googleMap.overlayMapTypes.removeAt(tileServerIndex);
    }
});

在上面的code,GoogleMap的是地图对象,tileServer是我实施google.maps.ImageMapType对象。

In the above code, googleMap is the map object, and tileServer is my implementation of a google.maps.ImageMapType object.

2)我应该回到重新present一个空的瓷砖?

2) What should I return to represent an empty tile?

我对这个问题的解决方案是相当多的清洁剂。我简单地列出服务器上的所有瓦片,这对被请求的瓦片的莫顿数目的基-4编码的文件名。然后,我这个列表发送到客户端作为字典从字符串为bool(总是如此)。客户端将进行检查,看是否包含服务器发出请求之前地图图块,因此服务器不必担心什么返回(我把它作为返回204错误,如果一个无效的请求时)。获得给getTileUrl方法中瓷砖的名字了JavaScript是如下:

My solution to this question was quite a bit cleaner. I simply list the file names of all the tiles on the server, which are a base-4 encoding of the Morton number for the tile being requested. Then I send this list to the client as a dictionary from string to bool (always true). The client simply checks to see if the server contains a map tile before making the request, so the server doesn't have to worry about what to return (I left it as returning a 204 error if an invalid request is made). The javascript to get the tile name within the getTileUrl method is as follows:

function(coord, zoom) {
    // Return null if the zoom level is not supported
    // NOTE: This should not be necessary, but minZoom and
    //       maxZoom parameters are ignored for image map types
    if (zoom < minZoom || maxZoom < zoom) {
        return null;
    }

    // Get the name of the map tile being requested
    var tileName = '';
    var y = coord.y << 1;
    for (var shift = zoom - 1; 0 <= shift; --shift) {
        var digit = (coord.x >>> shift) & 1;
        digit    |= (      y >>> shift) & 2;
        tileName += digit;
    }

    // Return if the map tile being requested does not exist
    if (!mapTiles[tileName]) {
        return null;
    }

    // Return the url to the tile server
    ...
}

这篇关于自定义地图图块叠加问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆