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

javascript - Custom Map Types: repeating maps and markers. How to adding padding to map? - Stack Overflow

programmeradmin1浏览0评论

With the Google Maps API (v3) I've created a custom map type for a fictional game world. By default, maps, even custom map types, repeat horizontally (see image below).


Larger Image here


Is it possible to keep the map from repeating horizontally? For my map, it does not represent a planet or spherical world, so having it repeat horizontally forever doesn't make sense at all. I have figured out how to simply not load tiles for the repeated maps on the left and right like so:

Larger Image here


HOWEVER, when you create markers, the markers still show up for all the repeated maps:

Larger Image here

Is it possible to keep the markers from repeating? Or is it possible to keep the map from repeating at all? That way I don't have to deal with markers repeating?


Work Around: Limit Panning beyond the Map Bounds I've read various work-arounds that discuss simply limiting how far the user can pan to the left or right. This won't work for me because I have to allow the user to zoom all the way out and view the entire map at once. If they zoom all the way out, repeated markers are still visible, which is unacceptable.


Is it possible to adding a bunch of padding to the map? That way there is a large amount of space between the maps:

Larger Image here

If I was able to add enough padding, then limiting the panning would work for me, because any repeated markers could be pushed far enough away by the padding that the user would never see them.


Finally my code, pretty simple:

(note: the map tile images I'm using are not available online yet)

<!DOCTYPE html>
<html style='height: 100%'>
    <head>
        <link rel="stylesheet" type="text/css" href="normalize.css" />
        <style>
            html, body { height: 100%;}
            #map_canvas { height: 1000px;}
        </style>


    </head>
    <body style='height: 100%'>
        <div id="map_canvas"></div>

        <script src=""></script>
        <script type='text/javascript'>

            var options =
            {
                getTileUrl: function(coord, zoom)
                {
                    // Don't load tiles for repeated maps
                    var tileRange = 1 << zoom;
                    if ( coord.y < 0 || coord.y >= tileRange || coord.x < 0 || coord.x >= tileRange )
                        return null;

                    // Load the tile for the requested coordinate
                    var file = 'images/zoom' + zoom + '/tile_' + zoom + '_' + (coord.x) + '_' + (coord.y) + '.jpg';

                    return file;
                },
                tileSize: new google.maps.Size(256, 256),
                minZoom: 1,
                maxZoom: 9,
                radius: 1738000, // I got this from an example in the api, I have no idea what this does
                name: 'Map',
            };

            var mapOptions =
            {
                center: new google.maps.LatLng(0,0),
                zoom: 2,
                backgroundColor: '#000',
                streetViewControl: false,
                mapTypeControl: false
            };

            var map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
            var mapType = new google.maps.ImageMapType(options);
            map.mapTypes.set('map', mapType);
            map.setMapTypeId('map');

            var marker = new google.maps.Marker({
                    position: new google.maps.LatLng(0,0),
                    map: map,
                    title: "Test"
            });

            </script>
    </body>
</html>

With the Google Maps API (v3) I've created a custom map type for a fictional game world. By default, maps, even custom map types, repeat horizontally (see image below).


Larger Image here


Is it possible to keep the map from repeating horizontally? For my map, it does not represent a planet or spherical world, so having it repeat horizontally forever doesn't make sense at all. I have figured out how to simply not load tiles for the repeated maps on the left and right like so:

Larger Image here


HOWEVER, when you create markers, the markers still show up for all the repeated maps:

Larger Image here

Is it possible to keep the markers from repeating? Or is it possible to keep the map from repeating at all? That way I don't have to deal with markers repeating?


Work Around: Limit Panning beyond the Map Bounds I've read various work-arounds that discuss simply limiting how far the user can pan to the left or right. This won't work for me because I have to allow the user to zoom all the way out and view the entire map at once. If they zoom all the way out, repeated markers are still visible, which is unacceptable.


Is it possible to adding a bunch of padding to the map? That way there is a large amount of space between the maps:

Larger Image here

If I was able to add enough padding, then limiting the panning would work for me, because any repeated markers could be pushed far enough away by the padding that the user would never see them.


Finally my code, pretty simple:

(note: the map tile images I'm using are not available online yet)

<!DOCTYPE html>
<html style='height: 100%'>
    <head>
        <link rel="stylesheet" type="text/css" href="normalize.css" />
        <style>
            html, body { height: 100%;}
            #map_canvas { height: 1000px;}
        </style>


    </head>
    <body style='height: 100%'>
        <div id="map_canvas"></div>

        <script src="https://maps.googleapis./maps/api/js?sensor=false"></script>
        <script type='text/javascript'>

            var options =
            {
                getTileUrl: function(coord, zoom)
                {
                    // Don't load tiles for repeated maps
                    var tileRange = 1 << zoom;
                    if ( coord.y < 0 || coord.y >= tileRange || coord.x < 0 || coord.x >= tileRange )
                        return null;

                    // Load the tile for the requested coordinate
                    var file = 'images/zoom' + zoom + '/tile_' + zoom + '_' + (coord.x) + '_' + (coord.y) + '.jpg';

                    return file;
                },
                tileSize: new google.maps.Size(256, 256),
                minZoom: 1,
                maxZoom: 9,
                radius: 1738000, // I got this from an example in the api, I have no idea what this does
                name: 'Map',
            };

            var mapOptions =
            {
                center: new google.maps.LatLng(0,0),
                zoom: 2,
                backgroundColor: '#000',
                streetViewControl: false,
                mapTypeControl: false
            };

            var map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
            var mapType = new google.maps.ImageMapType(options);
            map.mapTypes.set('map', mapType);
            map.setMapTypeId('map');

            var marker = new google.maps.Marker({
                    position: new google.maps.LatLng(0,0),
                    map: map,
                    title: "Test"
            });

            </script>
    </body>
</html>
Share Improve this question asked Nov 5, 2012 at 6:00 Jake WilsonJake Wilson 91.3k97 gold badges260 silver badges371 bronze badges 3
  • here: Dynamic google map with custom tiles prevent repeating pan – yodog Commented Nov 7, 2012 at 15:13
  • @RASG that only solves the panning limitation. Still need padding on the sides of the map. – Jake Wilson Commented Nov 7, 2012 at 15:45
  • Sorry, was about to close this as a dupe but then realized it wasn't. Feel free to re-apply the bounty. – casperOne Commented Nov 8, 2012 at 15:15
Add a ment  | 

4 Answers 4

Reset to default 4

In answer to the question: Is it possible to keep the markers from repeating?

Yes.

From Google Maps JavaScript API V3 Reference (3.19), if you set the markerOptions property optimized to false for your marker, it does not repeat but only shows up on the center map.

See: https://developers.google./maps/documentation/javascript/reference#MarkerOptions

So, in your code, I would modify var marker as such (adding optimized: false):

var marker = new google.maps.Marker({ position: new google.maps.LatLng(0,0), map: map, title: "Test" optimized: false });

According to Google's docs (I've added the bolding),

Optimization renders many markers as a single static element. Optimized rendering is enabled by default. Disable optimized rendering for animated GIFs or PNGs, or when each marker must be rendered as a separate DOM element (advanced usage only).

I set optimized to false and then looked through the page to find the id (or at least class) associated with my markers. I was going to make the "extra" markers non-visible. It turns out the elements are there but have no id or class. Just as I was contemplating other ways to identify them using jQuery, I happened to look up at my "map" and realized the "extra" markers were gone! ☺

A word of caution: based on Google's docs, I suspect this behavior (the "extra" markers not showing up) may be an unintended "feature".

Cheers, Bruce.

Looks to me like you just need to change your starting zoom and min zoom limit.

Even google runs into repeats when you are at zoom level 1, but it doesn't let you zoom out lower than that.

Just add minZoom and maxZoom properties to your options object to limit the zooming.

You can try to put a mask on the repeated area but I didn't tried it. This looks like it can solve your problem: Apply mask to Google Map. Update: Apply the mask only when you need it, i.e. when the zoom is the lowest. I don't think resizeing the browser window will affect anything in the map. It's also has nothing to do with the question and the problem is if the mask lays on top of the marker. Update 2: It's seems to be possible with v2 but not with v3. In v2 you can disable horizontal copies in the projection class: Google Maps API v3 with custom map image - markers repeating horizontally.

For those who has still this problem, have a look at my solution.

1- Set the maps zoom to (2) and add marker positions (lat,long) i.e

  var minZoomLevel = 2;
  map.setZoom(minZoomLevel);

  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < result.length; i++){
        var latlng = new google.maps.LatLng(result[i].Lat, result[i].Lng);
        bounds.extend(latlng);
    });

2- Attach a event listener on zoom changed i.e

google.maps.event.addListener(map, 'zoom_changed', function() {
        if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
    });

3- Attach a center changed listener (This done the trick) i.e

google.maps.event.addListener(map, 'center_changed', function() 
{ 
   checkBounds(bounds);
}

 function checkBounds(allowedBounds) {
    if(allowedBounds.contains(map.getCenter())) {
        return;
    }
    var mapCenter = map.getCenter();
    var X = mapCenter.lng();
    var Y = mapCenter.lat();

    var AmaxX = allowedBounds.getNorthEast().lng();
    var AmaxY = allowedBounds.getNorthEast().lat();
    var AminX = allowedBounds.getSouthWest().lng();
    var AminY = allowedBounds.getSouthWest().lat();

    if (X < AminX) {X = AminX;}
    if (X > AmaxX) {X = AmaxX;}
    if (Y < AminY) {Y = AminY;}
    if (Y > AmaxY) {Y = AmaxY;}

    map.setCenter(new google.maps.LatLng(Y,X));
}

Every time you change the center, it will check your points and restrict map to certain area . Setting zoom will show only one world tile, and check bound will restrict the horizontal scrolling !

发布评论

评论列表(0)

  1. 暂无评论