29 votes

Superposer les chemins d3 sur Google Maps?

Je suis en train d'essayer de superposer une carte sur Google Maps à l'aide de d3.geo et GeoJson. J'ai réussi à force de d3 à utiliser la Carte Google de la projection du dessin des chemins, qui a été étonnamment facile. Voici ce que j'ai à ce jour:

http://www.caudillweb.com/temp/d3_choropleth.html

Cela fonctionne bien comme je le zoom avant et arrière:

Map zoomed outMap zoomed in

Mais quand je pan, le SVG superposition bouge trop, et puisque sa taille est fixe, la forme que prennent tronqué:

Map panned down

Quelqu'un a obtenu quelque chose comme cela fonctionne? Des idées où je pourrais aller à partir d'ici? L'exemple ci-dessus est un simple fichier HTML autonome si quelqu'un veut jouer avec elle.

23voto

Derek Hunziker Points 6663

Dans cet exemple, la largeur et la hauteur du svg sont définies sur 8000 x 8000, ce qui semblait correct jusqu'à un niveau de zoom d'environ 9-10. Le haut et la gauche sont définis sur -4000 x -4000 pour le centrer. Enfin, la projection est décalée / décalée pour qu'elle dessine au centre du svg:

Agrandir et centrer le svg:

 .SvgOverlay svg {
    position: absolute;
    top: -4000px;
    left: -4000px;
    width: 8000px;
    height: 8000px;        
}
 

Décalez la projection:

 return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000];
 

4voto

Derek Hunziker Points 6663

Une option est de la taille de la carte à quelque chose de très grand, disons, 1000 x 1000 pixels ou plus. Cela va forcer le SVG superposition de rendre l'intérieur de la zone visible (ce qui semble être la contrainte avec Firefox). Je me rends compte que cela peut vis avec le design de votre site, de sorte que vous pourriez envisager d'emballage de la carte avec une div pour masquer le dépassement de capacité.

#map-wrap {
    width: 500px;
    height: 500px;
    overflow: hidden;
}

#map {
    width: 1000px; /* just big enough to show the whole thing at zoom #6 */
    height: 1000px;
}

Une fois la carte affichée, vous pouvez re-taille de la carte à la taille désirée de 500 x 500 et re-centrer la carte. Cela peut être fait dans l' bounds_changed événement:

google.maps.event.addListener(map, 'bounds_changed', function() {
    $map.css({ height: '500px', width: '500px' }); // back to desired dims
    google.maps.event.trigger(map, 'resize'); // trigger a 'refresh'
    map.setCenter(new google.maps.LatLng(-18.2, 35.1)); // re-center map
    google.maps.event.clearListeners(map, 'bounds_changed'); // don't do this again
});

Voici un exemple de travail (Testé avec Firefox et Chrome).

Quelques mises en garde:

  1. Le plus loin vous souhaitez autoriser les gens à faire un zoom avant, plus vous allez avoir besoin pour rendre l'initiale "temporaire" de la carte. Par exemple, si vous souhaitez autoriser pour le niveau de zoom 7, vous devrez peut-être faire la carte initiale de 2000 x 2000 pour compenser. Évidemment il y a des problèmes de performances lors du rendu d'une carte que les grandes. Que de disperser l'a souligné, il peut être sage de limiter les niveaux de zoom.
  2. En raison de la dernière minute de re-dimensionnement, il y aura un scintillement que la carte se réajuste. Vous pourriez envisager de masquer/afficher la carte à l'aide de jQuery, ou peut-être placer une superposition de couleur blanche sur le dessus de tout jusqu'à ce que la carte a fini de re-dimensionnement.

2voto

disperse Points 592

J'ai été en mesure de résoudre le problème à ce niveau de zoom en faisant le svg plus grand, ajoutant un peu de rembourrage, et de donner un négatif en haut et à gauche de la position de la sorte:

    .SvgOverlay, .SvgOverlay svg {
        position: absolute;
        top: -250px;
        left: -250px;
        padding: 500px;            
    }

    var svg = layer.append("svg")
          .attr("width", 1000)
          .attr("height", 1000)

Si vous souhaitez permettre à vos utilisateurs de zoomer plus loin, vous aurez à augmenter l'ensemble de ces numéros. L'augmentation par un facteur de 10, par exemple, semble corriger le problème pour tous les niveaux de zoom. Vous pouvez, cependant, veulent restreindre la capacité de l'utilisateur de zoomer comme l'utilité de la svg de superposition est réduite à mesure que vous zoomez plus loin.

Voici un Violon montrer l'idée. http://jsfiddle.net/VHWqq/7/

Edit: Comme d'Herbe points, cette approche ne fonctionne pas sur Firefox.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X