Changeset 54783 in spip-zone


Ignore:
Timestamp:
Nov 22, 2011, 2:29:23 PM (8 years ago)
Author:
fabrice.albert@…
Message:

Utilisation des scripts en ligne pour les librairies utilitaires de Google Maps (MarkerManager? sur Google Maps V2). Pour la librairie GoogleEarth? sur Google Maps API V3, il y a un bug connu sur les icones personnalisée, donc GMap conserve une version interne corrigée.
Mise à jour de la doc interne pour prendre en compte le paramètre "adresse" sur #GEOMARKER et <marker>.

Location:
_plugins_/gmap/trunk
Files:
2 added
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/gmap/trunk/html/fr/doc/balise-GEOMARKER.html

    r54597 r54783  
    1515<span class="spip-balise">#GEOMARKER</span><span class="spip-syntax">{id_document=119, type=visee}</span>
    1616<span class="spip-balise">#GEOMARKER</span><span class="spip-syntax">{latitude=38, longitude=-6, titre=un marqueur manuel, icon=gmap-marker-article, texte=toto}</span>
     17<span class="spip-balise">#GEOMARKER</span><span class="spip-syntax">{adresse='Montréal; Québec', titre=Montréal au Québec}</span>
    1718<span class="spip-balise">#GEOMARKER</span><span class="spip-syntax">{id_article=23, markers=documents}</span></pre>
    1819        <ul>
     
    2122                <li>La troisi&egrave;me ajoute le point de types <span class="code">visee</span> associ&eacute;e au document 119.</li>
    2223                <li>La quatri&egrave;me ajoute un point dont la position est d&eacute;finie manuellement.</li>
    23                 <li>La cinqui&egrave;me ajoute les points issus d'une requ&ecirc;te sur les documents de l'article 23.</li>
     24                <li>La cinqui&egrave;me ajoute un point dont la position est d&eacute;finie par une adresse.</li>
     25                <li>La sixi&egrave;me ajoute les points issus d'une requ&ecirc;te sur les documents de l'article 23.</li>
    2426        </ul>
    2527        <p>Si plusieurs balises GEOMAP sont pr&eacute;sentes, on peut utiliser le param&egrave;tre map=X pour donner un num&eacute;ro &agrave; la carte et lever les ambigu&iuml;t&eacute;s. Sans ce param&egrave;tre, le marqueur sera ajout&eacute; sur la derni&egrave;re carte cr&eacute;&eacute;e au moment o&ugrave; la balise GEOMARKER est interpr&eacute;t&eacute;e.</p>
     
    3638        <p>Les param&egrave;tres sp&eacute;cifiques &agrave; une impl&eacute;mentation, ainsi que le param&egrave;tre <span class="code">viewport</span> n'ont aucun sens dans le cadre de l'ajout de points, il ne sont donc pas utilis&eacute;s.</p>
    3739        <p>N'apparaissent ci-dessous que les param&egrave;tres sp&eacute;cifiques ou dont le sens est diff&eacute;rent.</p>
     40        <p>&nbsp;</p>
    3841        <table>
    3942                <tr><th>Nom</th><th>Description</th><th>Valeur</th></tr>
     
    5962                </tr>
    6063                <tr>
     64                        <td>adresse</td>
     65                        <td>Adresse du point, au format connu par le geocoder <a href="#note1">(cf. note 1)</a>.</td>
     66                        <td>Montr&eacute;al; Qu&eacute;bec</td>
     67                </tr>
     68                <tr>
    6169                        <td>titre</td>
    6270                        <td>Titre du point, affich&eacute; sur le survol du marqueur.</td>
     
    7179                        <td>icon</td>
    7280                        <td>Nom de l'icone utilis&eacute;e pour le marqueur.</td>
    73                         <td>Nom d'un fichier XML du type gmd. Le plugin d&eacute;fini par exemple un fichier <span class="code">gmap-marker-default.gmd</span>, pour le d&eacute;signer, le param&egrave;tre <i>icon</i> doit contenir <i>gmap-marker-default</i>. Ces fichiers sont recherch&eacute;s dans le path de SPIP, ils peuvent donc &ecirc;tre positionn&eacute;s dans le dossier <i>squelettes</i>.</td>
     81                        <td>Nom d'un fichier XML du type gmd <a href="#note1">(cf. note 2)</a>.</td>
    7482                </tr>
    7583        </table>
     84        <a name="note1"></a><p>Note 1&nbsp;: L'adresse est exprim&eacute;e d'une fa&ccedil;on compr&eacute;hensible par le geocoder de l'impl&eacute;mentation utilis&eacute;e, mais il ne peut comporter de virgules, car SPIP les interpr&egrave;te comme le passage au param&egrave;tre suivant. Pour s&eacute;parer les diff&eacute;rents champs, vous pouvez utiliser des points virgules.</p>
     85        <a name="note2"></a><p>Note 2&nbsp;: Le plugin d&eacute;fini par exemple un fichier <span class="code">gmap-marker-default.gmd</span>, pour le d&eacute;signer, le param&egrave;tre <i>icon</i> doit contenir <i>gmap-marker-default</i>. Ces fichiers sont recherch&eacute;s dans le path de SPIP, ils peuvent donc &ecirc;tre positionn&eacute;s dans le dossier <i>squelettes</i>.</p>
    7686       
    7787</body>
  • _plugins_/gmap/trunk/html/fr/doc/modele-marker.html

    r54597 r54783  
    8282                </tr>
    8383                <tr>
     84                        <td>adresse</td>
     85                        <td>Adresse du point, au format connu par le geocoder.</td>
     86                        <td>Montr&eacute;al, Qu&eacute;bec</td>
     87                        <td>absent</td>
     88                </tr>
     89                <tr>
    8490                        <td>titre</td>
    8591                        <td>Titre du point, affich&eacute; sur le survol du marqueur.</td>
  • _plugins_/gmap/trunk/mapimpl/gma2/public/script_init.php

    r52218 r54783  
    3030       
    3131        // Ajouter le markermanager (copie en local)
    32         $manager = find_in_path('mapimpl/gma2/javascript/markermanager.js');
     32        $manager = "http://gmaps-utility-library-dev.googlecode.com/svn/tags/markermanager/1.1/src/markermanager.js";
    3333        $out .= '<script type="text/javascript" src="'.$manager.'"></script>'."\n";
    3434       
  • _plugins_/gmap/trunk/mapimpl/gma3/javascript/gmap_impl_public.js

    r54597 r54783  
    12221222                var markers = null;
    12231223                var bounds = null;
    1224                 if (this.curParams.mergeInfoWindows === true)
     1224                if ((this.curParams.mergeInfoWindows === true) &&
     1225                        (this.map.getMapTypeId() != GoogleEarth.MAP_TYPE_ID))
    12251226                {
    12261227                        bounds = this._getMarkerAttraction(marker);
  • _plugins_/gmap/trunk/mapimpl/gma3/javascript/googleearth.js

    r52218 r54783  
    1 (function(){var j=window,k=document,l=Math;function n(a,b){return a.width=b}function o(a,b){return a.position=b}function p(a,b){return a.height=b}function q(a,b){return a.zIndex=b}var r="appendChild",s="createElement",t="getCoordinates",u="getView",w="pushLatLngAlt",x="setTimeout",y="style",z="addListener",A="getFeatures",B="InfoWindow",C="maps",D="getPosition",E="setStyleSelector",F="earth",H="prototype",I="setGeometry",J="substring",K="parentNode",L="event";
    2 function M(a){if(!google||!google[F])throw"google.earth not loaded";if(!google[F].isSupported())throw"Google Earth API is not supported on this system";if(!google[F].isInstalled())throw"Google Earth API is not installed on this system";this.l="http://maps.google.com/mapfiles/kml/paddle/red-circle.png";this.b=a;this.k=a.getDiv();this.d=!1;this.f="Earth";this.i=[];this.e={};this.j=null;this.g=0;aa(this);ba(this)}j.GoogleEarth=M;M.MAP_TYPE_ID="GoogleEarthAPI";M[H].o=function(){return this.a};
    3 M[H].getInstance=M[H].o;
    4 function aa(a){var b=a.b,c={tileSize:new google[C].Size(256,256),maxZoom:19,name:a.f,alt:a.f,getTile:function(a,b,c){return c[s]("DIV")}};b.mapTypes.set("GoogleEarthAPI",c);b.setOptions({mapTypeControlOptions:{mapTypeIds:[google[C].MapTypeId.ROADMAP,google[C].MapTypeId.SATELLITE,"GoogleEarthAPI"]}});google[C][L][z](b,"maptypeid_changed",function(){if(a.b.getMapTypeId()=="GoogleEarthAPI"){var b;a:{b=RegExp("title=['\"]?"+a.f+"[\"']?");for(var c=a.c[K].childNodes,e=0,g;g=c[e];e++)if(b.test(g.innerHTML)){b=g;
    5 break a}b=void 0}c=b;e=c[y].zIndex;g=a.c[K].childNodes;for(var h=0,i;i=g[h];h++)i.__gme_ozi=i[y].zIndex,q(i[y],-1);c.__gme_ozi=e;q(a.c[y],q(c[y],0));c=a.h=k[s]("IFRAME");c.src="javascript:false;";c.scrolling="no";c.frameBorder="0";e=c[y];q(e,-1E5);n(e,p(e,"100%"));o(e,"absolute");e.left=e.top=0;b[r](c);a.c[y].display="";a.d=!0;a.a?N(a):ca(a)}else da(a)})}
    6 function N(a){a.e={};O(a,!0);for(var b=a.a[A]();b.getFirstChild();)b.removeChild(b.getFirstChild());a.g++;for(var b=0,c;c=a.i[b];b++)google[C][L].removeListener(c);b={};c=P;for(var d=0,f;f=c[d];d++)b[f]=Q(a,f);for(c=0;d=b.Marker[c];c++)ea(a,d);for(c=0;d=b.Polygon[c];c++){var e=a,g=d,d=e.a;f=S(e,g);var h=d.createPolygon("");f[I](h);e=T(e,g);f[E](e);e=d.createLinearRing("");h.setOuterBoundary(e);for(var h=e[t](),g=g.getPath().getArray(),e=0,i=void 0;i=g[e];e++)h[w](i.lat(),i.lng(),0);d[A]()[r](f)}for(c=
    7 0;d=b.Polyline[c];c++){h=a;g=d;d=h.a;f=S(h,g);e=d.createLineString("");e.setTessellate(!0);f[I](e);h=T(h,g);f[E](h);h=e[t]();g=g.getPath().getArray();e=0;for(i=void 0;i=g[e];e++)h[w](i.lat(),i.lng(),0);d[A]()[r](f)}for(c=0;d=b.Rectangle[c];c++){var g=a,m=d,d=g.a,h=m.getBounds();f=h.getNorthEast();h=h.getSouthWest();e=S(g,m);e[I](d.createPolygon(""));i=d.createLinearRing("");g=T(g,m);e[E](g);g=i[t]();g[w](f.lat(),f.lng(),0);g[w](f.lat(),h.lng(),0);g[w](h.lat(),h.lng(),0);g[w](h.lat(),f.lng(),0);g[w](f.lat(),
    8 f.lng(),0);e.getGeometry().setOuterBoundary(i);e.setName("placemark");d[A]()[r](e)}for(c=0;d=b.Circle[c];c++){i=a;m=d;d=i.a;f=m.getCenter();g=m.getRadius();h=S(i,m);h[I](d.createPolygon(""));e=d.createLinearRing("");i=T(i,m);h[E](i);for(i=0;i<25;i++){var R=f,v=g,m=14.4*i;v/=6378137;m*=l.PI/180;var G=R.lat()*(l.PI/180),R=R.lng()*(l.PI/180),X=l.cos(v),v=l.sin(v),Y=l.sin(G),G=l.cos(G),Z=X*Y+v*G*l.cos(m),m=new google[C].LatLng(l.asin(Z)/(l.PI/180),(R+l.atan2(v*G*l.sin(m),X-Y*Z))/(l.PI/180));e[t]()[w](m.lat(),
    9 m.lng(),0)}h.getGeometry().setOuterBoundary(e);h.setName("placemark");d[A]()[r](h)}for(c=0;d=b.KmlLayer[c];c++)fa(a,d.getUrl());for(c=0;d=b.GroundOverlay[c];c++)g=d.getBounds(),f=g.getNorthEast(),g=g.getSouthWest(),h=a.a,e=h.createGroundOverlay(""),e.setLatLonBox(h.createLatLonBox("")),e.getLatLonBox().setBox(f.lat(),g.lat(),f.lng(),g.lng(),0),e.setIcon(h.createIcon("")),e.getIcon().setHref(d.getUrl()),h[A]()[r](e)}
    10 function O(a,b){var c=a.b.getCenter(),d=a.a.createLookAt("");d.setRange(l.pow(2,27-a.b.getZoom()));d.setLatitude(c.lat());d.setLongitude(c.lng());d.setHeading(0);d.setAltitude(0);var f=a.a;b?(f.getOptions().setFlyToSpeed(5),f[u]().setAbstractView(d),d.setTilt(15),f.getOptions().setFlyToSpeed(0.75),j[x](function(){f[u]().setAbstractView(d)},200),j[x](function(){f.getOptions().setFlyToSpeed(1)},250)):f[u]().setAbstractView(d)}
    11 function U(a,b){a[0]=="#"&&(a=a[J](1,9));typeof b=="undefined"?b="FF":(b=parseInt(parseFloat(b)*255,10).toString(16),b.length==1&&(b="0"+b));return[b,a[J](4,6),a[J](2,4),a[J](0,2)].join("")}function S(a,b){var c=a.g+"GEV3_"+b.__gme_id;a.e[c]=b;return a.a.createPlacemark(c)}function fa(a,b){var c=a.a;google[F].fetchKml(c,b,function(a){a?c[A]()[r](a):j[x](function(){alert("Bad or null KML.")},0)})}
    12 function ea(a,b){if(b[D]()){var c=a.a,d=S(a,b);b.getTitle()&&d.setName(b.getTitle());var f=c.createIcon("");b.getIcon()?f.setHref(b.getIcon()):f.setHref(a.l);var e=c.createStyle("");e.getIconStyle().setIcon(f);d[E](e);f=c.createPoint("");f.setLatitude(b[D]().lat());f.setLongitude(b[D]().lng());d[I](f);c[A]()[r](d);a.i.push(google[C][L][z](b,"position_changed",function(){var c=a.g+"GEV3_"+b.__gme_id,d=a.e[c],c=a.a.getElementById(c).getGeometry(),d=d[D]();c.setLatitude(d.lat());c.setLongitude(d.lng())}))}}
    13 function T(a,b){var c=a.a.createStyle(""),d=c.getPolyStyle(),f=c.getLineStyle();f.setWidth(V(b,"strokeWeight",3));var e=V(b,"strokeOpacity",1),g=V(b,"fillOpacity",0.3),h=V(b,"strokeColor","#000000"),i=V(b,"fillColor","#000000");f.getColor().set(U(h,e));d.getColor().set(U(i,g));return c}function V(a,b,c){a=a.get(b);return typeof a=="undefined"?c:a}
    14 function ca(a){google[F].createInstance(a.m,function(b){a.a=b;ga(a);N(a)},function(b){ha(a);a.b.setMapTypeId(google[C].MapTypeId.ROADMAP);throw"Google Earth API failed to initialize: "+b;})}
    15 function ga(a){var b=a.a;b.getWindow().setVisibility(!0);var c=b.getNavigationControl();c.setVisibility(b.VISIBILITY_AUTO);c=c.getScreenXY();c.setYUnits(b.UNITS_INSET_PIXELS);c.setXUnits(b.UNITS_PIXELS);c=b.getLayerRoot();c.enableLayerById(b.LAYER_BORDERS,!0);c.enableLayerById(b.LAYER_ROADS,!0);google[C][L][z](a.b,"GEInfoWindowOpened",function(b){if(a.d){var c=a.a.createHtmlStringBalloon("");c.setFeature(a.j);c.setContentString(b.getContent());a.a.setBalloon(c)}});google[F].addEventListener(b.getGlobe(),
    16 "click",function(b){var c=b.getTarget(),e=a.e[c.getId()];if(e){b.preventDefault();for(var b=Q(a,"InfoWindow"),g=0,h;h=b[g];g++)h.close();a.j=c;google[C][L].trigger(e,"click")}})}function ia(a){var b=a.a[u]().copyAsLookAt(a.a.ALTITUDE_RELATIVE_TO_GROUND),c=b.getRange(),c=l.round(27-l.log(c)/l.log(2));!a.b.getZoom()==c?a.b.setZoom(c-1):a.b.setZoom(c);a.b.panTo(new google[C].LatLng(b.getLatitude(),b.getLongitude()))}function da(a){a.d&&(ia(a),j[x](function(){O(a)},50),j[x](function(){ha(a)},2200))}
    17 function ha(a){for(var b=a.c[K].childNodes,c=0,d;d=b[c];c++)q(d[y],d.__gme_ozi);a.h[K].removeChild(a.h);a.h=null;a.c[y].display="none";a.d=!1}
    18 function ba(a){var b=a.k,c=a.c=k[s]("DIV");o(c[y],"absolute");n(c[y],0);p(c[y],0);c.index=0;c[y].display="none";var d=a.n=k[s]("DIV");n(d[y],b.clientWidth+"px");p(d[y],b.clientHeight+"px");o(d[y],"absolute");c[r](d);b=a.m=k[s]("DIV");o(b[y],"absolute");n(b[y],"100%");p(b[y],"100%");d[r](b);a.b.controls[google[C].ControlPosition.TOP_LEFT].push(c);google[C][L][z](a.b,"resize",function(){var b=a.n[y],c=a.k;n(b,c.clientWidth+"px");p(b,c.clientHeight+"px")})}
    19 function Q(a,b){var c=[],d=W[b],f;for(f in d)if(d.hasOwnProperty(f)){var e=d[f];e.get("map")==a.b&&c.push(e)}return c}var W={};function ja(){var a=$,b=google[C][a][H];b.__gme_setMapOriginal=b.setMap;W[a]={};google[C][a][H].setMap=function(b){if(b){if(!this.__gme_id)this.__gme_id=ka++,W[a][this.__gme_id]=this}else delete W[a][this.__gme_id],this.__gme_id=void 0;this.__gme_setMapOriginal(b)}}
    20 for(var P="Marker,Polyline,Polygon,Rectangle,Circle,KmlLayer,GroundOverlay,InfoWindow".split(","),ka=0,la=P,ma=0,$;$=la[ma];ma++)if(ja(),$=="InfoWindow")google[C][B][H].p=google[C][B][H].open,W.InfoWindow={},google[C][B][H].open=function(a,b){if(a){if(!this.__gme_id)this.__gme_id=ka++,W[B][this.__gme_id]=this}else delete W[B][this.__gme_id],this.__gme_id=void 0;google[C][L].trigger(a,"GEInfoWindowOpened",this);this.p(a,b)};})();
     1// Copyright 2011 Google Inc. All Rights Reserved.
     2
     3/**
     4 * @fileoverview Earth API library for Maps v3.
     5 * usage:  var ge = new GoogleEarth(map);.
     6 * @author jlivni@google.com (Josh Livni).
     7 */
     8
     9/**
     10 * @constructor
     11 * @param {google.maps.Map} map the Map associated with this Earth instance.
     12 */
     13function GoogleEarth(map) {
     14  if (!google || !google.earth) {
     15    throw 'google.earth not loaded';
     16  }
     17
     18  if (!google.earth.isSupported()) {
     19    throw 'Google Earth API is not supported on this system';
     20  }
     21
     22  if (!google.earth.isInstalled()) {
     23    throw 'Google Earth API is not installed on this system';
     24  }
     25
     26  /**
     27   * @const
     28   * @private
     29   * @type {string} */
     30  this.RED_ICON_ = 'http://maps.google.com/mapfiles/kml/paddle/red-circle.png';
     31
     32  /**
     33   * @private
     34   * @type {google.maps.Map} */
     35  this.map_ = map;
     36
     37  /**
     38   * @private
     39   * @type {Node} */
     40  this.mapDiv_ = map.getDiv();
     41
     42  /**
     43   * @private
     44   * @type {boolean} */
     45  this.earthVisible_ = false;
     46
     47  /**
     48   * @private
     49   * @type {string} */
     50  this.earthTitle_ = 'Earth';
     51
     52  /**
     53   * @private
     54   * @type {Object} */
     55  this.moveEvents_ = [];
     56
     57  /**
     58   * @private
     59   * @type {Object} */
     60  this.overlays_ = {};
     61
     62  /**
     63   * @private
     64   * @type {?Object} */
     65  this.lastClickedPlacemark_ = null;
     66
     67  /**
     68   * Keep track of each time the 3D view is reloaded/refreshed
     69   * @private
     70   * @type {number} */
     71  this.displayCounter_ = 0;
     72
     73  this.addEarthMapType_();
     74  this.addEarthControl_();
     75}
     76window['GoogleEarth'] = GoogleEarth;
     77
     78/**
     79 * @const
     80 * @type {string} */
     81GoogleEarth.MAP_TYPE_ID = 'GoogleEarthAPI';
     82GoogleEarth['MAP_TYPE_ID'] = GoogleEarth.MAP_TYPE_ID;
     83
     84/**
     85 * @const
     86 * @private
     87 * @type {string}
     88 */
     89GoogleEarth.INFO_WINDOW_OPENED_EVENT_ = 'GEInfoWindowOpened';
     90
     91/**
     92 * @const
     93 * @private
     94 * @type {number}
     95 */
     96GoogleEarth.MAX_EARTH_ZOOM_ = 27;
     97
     98/**
     99 * @return {?google.earth.GEPlugin} The Earth API Instance.
     100 */
     101GoogleEarth.prototype.getInstance = function() {
     102  return this.instance_;
     103};
     104GoogleEarth.prototype['getInstance'] = GoogleEarth.prototype.getInstance;
     105
     106/**
     107 * @private
     108 */
     109GoogleEarth.prototype.addEarthMapType_ = function() {
     110  var map = this.map_;
     111
     112  var earthMapType = /** @type {google.maps.MapType} */({
     113    tileSize: new google.maps.Size(256, 256),
     114    maxZoom: 19,
     115    name: this.earthTitle_,
     116    // The alt helps the findMapTypeControlDiv work.
     117    alt: this.earthTitle_,
     118    getTile:
     119      /**
     120       * @param {google.maps.Point} tileCoord the tile coordinate.
     121       * @param {number} zoom the zoom level.
     122       * @param {Node} ownerDocument n/a.
     123       * @return {Node} the overlay.
     124       */
     125      function(tileCoord, zoom, ownerDocument) {
     126        var div = ownerDocument.createElement('DIV');
     127        return div;
     128      }
     129  });
     130
     131  map.mapTypes.set(GoogleEarth.MAP_TYPE_ID, earthMapType);
     132
     133  var options = /** @type {google.maps.MapTypeControlOptions} */({
     134    mapTypeControlOptions: {
     135      mapTypeIds: [google.maps.MapTypeId.ROADMAP,
     136                   google.maps.MapTypeId.SATELLITE,
     137                   GoogleEarth.MAP_TYPE_ID]
     138    }
     139  });
     140
     141  map.setOptions(options);
     142
     143  var that = this;
     144  google.maps.event.addListener(map, 'maptypeid_changed', function() {
     145    that.mapTypeChanged_();
     146  });
     147};
     148
     149/**
     150 * @private
     151 */
     152GoogleEarth.prototype.mapTypeChanged_ = function() {
     153  if (this.map_.getMapTypeId() == GoogleEarth.MAP_TYPE_ID) {
     154    this.showEarth_();
     155  } else {
     156    this.switchToMapView_();
     157  }
     158};
     159
     160/**
     161 * @private
     162 */
     163GoogleEarth.prototype.showEarth_ = function() {
     164  var mapTypeControlDiv = this.findMapTypeControlDiv_();
     165  this.setZIndexes_(mapTypeControlDiv);
     166  this.addShim_(mapTypeControlDiv);
     167
     168  this.controlDiv_.style.display = '';
     169
     170  this.earthVisible_ = true;
     171  if (!this.instance_) {
     172    this.initializeEarth_();
     173    return;
     174  }
     175  this.refresh_();
     176};
     177
     178/**
     179 * @private
     180 */
     181GoogleEarth.prototype.refresh_ = function() {
     182  this.overlays_ = {};
     183  this.flyToMapView_(true);
     184  this.clearPlacemarks_();
     185  this.displayCounter_++;
     186  this.clearMoveEvents_();
     187  this.addMapOverlays_();
     188};
     189
     190/**
     191 * Clear all marker position_changed events
     192 * @private
     193 */
     194GoogleEarth.prototype.clearMoveEvents_ = function() {
     195  for (var i = 0, evnt; evnt = this.moveEvents_[i]; i++) {
     196    google.maps.event.removeListener(evnt);
     197  }
     198};
     199
     200/**
     201 * Clear all features on this instance.
     202 * @private
     203 */
     204GoogleEarth.prototype.clearPlacemarks_ = function() {
     205  var features = this.instance_.getFeatures();
     206  while (features.getFirstChild()) {
     207    features.removeChild(features.getFirstChild());
     208  }
     209};
     210
     211/**
     212 * Fly to the current map zoom, add slight tilt.
     213 * @private
     214 * @param {boolean} tilt whether to teleport and tilt, or just flyto.
     215 */
     216GoogleEarth.prototype.flyToMapView_ = function(tilt) {
     217  var center = this.map_.getCenter();
     218  var lookAt = this.instance_.createLookAt('');
     219  var range = Math.pow(2, GoogleEarth.MAX_EARTH_ZOOM_ - this.map_.getZoom());
     220  lookAt.setRange(range);
     221  lookAt.setLatitude(center.lat());
     222  lookAt.setLongitude(center.lng());
     223  lookAt.setHeading(0);
     224  lookAt.setAltitude(0);
     225  var ge = this.instance_;
     226  if (tilt) {
     227    // Teleport to the pre-tilt view immediately.
     228    ge.getOptions().setFlyToSpeed(5);
     229    ge.getView().setAbstractView(lookAt);
     230    lookAt.setTilt(15);
     231    // Fly to the tilt at regular speed in 200ms
     232    ge.getOptions().setFlyToSpeed(0.75);
     233    window.setTimeout(function() {
     234      ge.getView().setAbstractView(lookAt);
     235    }, 200);
     236    // Set the flyto speed back to default after the animation starts.
     237    window.setTimeout(function() {
     238      ge.getOptions().setFlyToSpeed(1);
     239    }, 250);
     240  } else {
     241    // Fly to the approximate map view at regular speed.
     242    ge.getView().setAbstractView(lookAt);
     243  }
     244};
     245
     246/**
     247 *  @param {string|*} hex color value in rgb.
     248 *  @param {string|*=} opacity -- in percentage.
     249 *  @return {string} abgr KML style color.
     250 *  @private
     251 */
     252GoogleEarth.getKMLColor_ = function(hex, opacity) {
     253  if (hex[0] == '#') {
     254    hex = hex.substring(1, 9);
     255  }
     256  if (typeof opacity == 'undefined') {
     257    opacity = 'FF';
     258  } else {
     259    opacity = parseInt(parseFloat(opacity) * 255, 10).toString(16);
     260    if (opacity.length == 1) {
     261      opacity = '0' + opacity;
     262    }
     263  }
     264  var R = hex.substring(0, 2);
     265  var G = hex.substring(2, 4);
     266  var B = hex.substring(4, 6);
     267  var abgr = [opacity, B, G, R].join('');
     268  return abgr;
     269};
     270
     271
     272/**
     273 * @param {google.maps.MVCObject} overlay the map overlay.
     274 * @return {String} ID for the Placemark.
     275 * @private
     276 */
     277GoogleEarth.prototype.generatePlacemarkId_ = function(overlay) {
     278  var placemarkId = this.displayCounter_ + 'GEV3_' + overlay['__gme_id'];
     279  return placemarkId;
     280};
     281
     282/**
     283 * @param {google.maps.MVCObject} overlay the map overlay.
     284 * @return {google.earth.KmlPlacemark} placemark the placemark.
     285 * @private
     286 */
     287GoogleEarth.prototype.createPlacemark_ = function(overlay) {
     288  var placemarkId = this.generatePlacemarkId_(overlay);
     289  this.overlays_[placemarkId] = overlay;
     290  return this.instance_.createPlacemark(placemarkId);
     291};
     292
     293/**
     294 * @param {google.maps.Rectangle} rectangle the rectangle overlay.
     295 * @private
     296 */
     297GoogleEarth.prototype.createRectangle_ = function(rectangle) {
     298  var ge = this.instance_;
     299  var bounds = rectangle.getBounds();
     300  var ne = bounds.getNorthEast();
     301  var sw = bounds.getSouthWest();
     302
     303  var placemark = this.createPlacemark_(rectangle);
     304
     305  placemark.setGeometry(ge.createPolygon(''));
     306  var ring = ge.createLinearRing('');
     307
     308  //set the style
     309  var style = this.createStyle_(rectangle);
     310  placemark.setStyleSelector(style);
     311
     312  //create the rectangle
     313  var coords = ring.getCoordinates();
     314  coords.pushLatLngAlt(ne.lat(), ne.lng(), 0);
     315  coords.pushLatLngAlt(ne.lat(), sw.lng(), 0);
     316  coords.pushLatLngAlt(sw.lat(), sw.lng(), 0);
     317  coords.pushLatLngAlt(sw.lat(), ne.lng(), 0);
     318  coords.pushLatLngAlt(ne.lat(), ne.lng(), 0);
     319
     320  placemark.getGeometry().setOuterBoundary(ring);
     321  placemark.setName('placemark');
     322  ge.getFeatures().appendChild(placemark);
     323};
     324
     325/**
     326 * @param {google.maps.GroundOverlay} groundOverlay the GroundOverlay.
     327 * @private
     328 */
     329GoogleEarth.prototype.addGroundOverlay_ = function(groundOverlay) {
     330  var bounds = groundOverlay.getBounds();
     331  var ne = bounds.getNorthEast();
     332  var sw = bounds.getSouthWest();
     333
     334  var ge = this.instance_;
     335  var overlay = ge.createGroundOverlay('');
     336
     337  overlay.setLatLonBox(ge.createLatLonBox(''));
     338  var latLonBox = overlay.getLatLonBox();
     339  latLonBox.setBox(ne.lat(), sw.lat(), ne.lng(), sw.lng(), 0);
     340
     341  overlay.setIcon(ge.createIcon(''));
     342  overlay.getIcon().setHref(groundOverlay.getUrl());
     343
     344  ge.getFeatures().appendChild(overlay);
     345};
     346
     347/**
     348 * @param {string} url for kml.
     349 * @private
     350 */
     351GoogleEarth.prototype.addKML_ = function(url) {
     352  var ge = this.instance_;
     353  google.earth.fetchKml(ge, url, function(kml) {
     354    if (!kml) {
     355      // wrap alerts in API callbacks and event handlers
     356      // in a window.setTimeout to prevent deadlock in some browsers
     357      window.setTimeout(function() {
     358        alert('Bad or null KML.');
     359      }, 0);
     360      return;
     361    }
     362    ge.getFeatures().appendChild(kml);
     363 });
     364};
     365
     366/**
     367 * @param {String} placemarkId the id of the placemark.
     368 * @private
     369 */
     370GoogleEarth.prototype.updatePlacemark_ = function(placemarkId) {
     371  //TODO(jlivni) generalize to work with more than just Markers/Points
     372  var marker = this.overlays_[placemarkId];
     373  var placemark = this.instance_.getElementById(placemarkId);
     374  var geom = placemark.getGeometry();
     375  var position = marker.getPosition();
     376  geom.setLatitude(position.lat());
     377  geom.setLongitude(position.lng());
     378};
     379
     380/**
     381 * @param {google.maps.Marker} marker The map marker.
     382 * @private
     383 */
     384GoogleEarth.prototype.createPoint_ = function(marker) {
     385  if (!marker.getPosition()) {
     386    return;
     387  }
     388  var ge = this.instance_;
     389  var placemark = this.createPlacemark_(marker);
     390  if (marker.getTitle()) {
     391    placemark.setName(marker.getTitle());
     392  }
     393
     394  // Create style map for placemark
     395  var icon = ge.createIcon('');
     396  if (marker.getIcon()) {
     397    //TODO(jlivni) fix for if it's a markerImage
     398        // FAB >>> fix it !
     399    //icon.setHref(marker.getIcon());
     400        var url = marker.getIcon();
     401        if (url instanceof google.maps.MarkerImage)
     402                url = url.url;
     403    icon.setHref(url);
     404        // <<< FAB
     405  } else {
     406    icon.setHref(this.RED_ICON_);
     407  }
     408
     409  var style = ge.createStyle('');
     410  style.getIconStyle().setIcon(icon);
     411  placemark.setStyleSelector(style);
     412
     413  // Create point
     414  var point = ge.createPoint('');
     415  point.setLatitude(marker.getPosition().lat());
     416  point.setLongitude(marker.getPosition().lng());
     417  placemark.setGeometry(point);
     418
     419  ge.getFeatures().appendChild(placemark);
     420
     421  //add listener for marker move on Map
     422  var that = this;
     423  var moveEvent = google.maps.event.addListener(marker,
     424    'position_changed',
     425    function() {
     426      var placemarkId = that.generatePlacemarkId_(marker);
     427      that.updatePlacemark_(placemarkId);
     428    });
     429  this.moveEvents_.push(moveEvent);
     430};
     431
     432/**
     433 * @param {google.maps.Polygon} polygon the polygon overlay.
     434 * @private
     435 */
     436GoogleEarth.prototype.createPolygon_ = function(polygon) {
     437  var ge = this.instance_;
     438  var placemark = this.createPlacemark_(polygon);
     439
     440  // Create polygon
     441  var poly = ge.createPolygon('');
     442  placemark.setGeometry(poly);
     443
     444  //set the style
     445  var style = this.createStyle_(polygon);
     446  placemark.setStyleSelector(style);
     447
     448
     449  //assume single linearRing
     450  var outer = ge.createLinearRing('');
     451  poly.setOuterBoundary(outer);
     452  var coords = outer.getCoordinates();
     453  var path = polygon.getPath().getArray();
     454
     455  //TODO(jlivni) use getPaths and multiple rings
     456  for (var i = 0, latLng; latLng = path[i]; i++) {
     457    coords.pushLatLngAlt(latLng.lat(), latLng.lng(), 0);
     458  }
     459
     460  ge.getFeatures().appendChild(placemark);
     461};
     462
     463/**
     464 * Computes the LatLng produced by starting from a given LatLng and heading a
     465 * given distance.
     466 * @see http://williams.best.vwh.net/avform.htm#LL
     467 * @param {google.maps.LatLng} from The LatLng from which to start.
     468 * @param {number} distance The distance to travel.
     469 * @param {number} heading The heading in degrees clockwise from north.
     470 * @return {google.maps.LatLng} The result.
     471 * @private
     472 */
     473GoogleEarth.computeOffset_ = function(from, distance, heading) {
     474  var radius = 6378137;
     475  distance /= radius;
     476  heading = heading * (Math.PI / 180); //convert to radians
     477  var fromLat = from.lat() * (Math.PI / 180);
     478  var fromLng = from.lng() * (Math.PI / 180);
     479  var cosDistance = Math.cos(distance);
     480  var sinDistance = Math.sin(distance);
     481  var sinFromLat = Math.sin(fromLat);
     482  var cosFromLat = Math.cos(fromLat);
     483  var sinLat = cosDistance * sinFromLat +
     484      sinDistance * cosFromLat * Math.cos(heading);
     485  var dLng = Math.atan2(
     486      sinDistance * cosFromLat * Math.sin(heading),
     487      cosDistance - sinFromLat * sinLat);
     488  return new google.maps.LatLng((Math.asin(sinLat) / (Math.PI / 180)),
     489                                (fromLng + dLng) / (Math.PI / 180));
     490};
     491
     492/**
     493 * @param {google.maps.Circle} circle The circle overlay.
     494 * @private
     495 */
     496GoogleEarth.prototype.createCircle_ = function(circle) {
     497  var ge = this.instance_;
     498  var center = circle.getCenter();
     499  var radius = circle.getRadius();
     500  var placemark = this.createPlacemark_(circle);
     501  placemark.setGeometry(ge.createPolygon(''));
     502  var ring = ge.createLinearRing('');
     503
     504  //set the style
     505  var style = this.createStyle_(circle);
     506  placemark.setStyleSelector(style);
     507
     508  //create a circle
     509  var vertices = 25;
     510  for (var i = 0; i < vertices; i++) {
     511    var heading = 360 / vertices * i;
     512    var offset = GoogleEarth.computeOffset_(center, radius, heading);
     513    ring.getCoordinates().pushLatLngAlt(offset.lat(), offset.lng(), 0);
     514  }
     515  placemark.getGeometry().setOuterBoundary(ring);
     516  placemark.setName('placemark');
     517  ge.getFeatures().appendChild(placemark);
     518};
     519
     520/**
     521 * @param {google.maps.Polyline} polyline The map polyline overlay.
     522 * @private
     523 */
     524GoogleEarth.prototype.createPolyline_ = function(polyline) {
     525  var ge = this.instance_;
     526  var placemark = this.createPlacemark_(polyline);
     527
     528  // Create linestring
     529  var lineString = ge.createLineString('');
     530  lineString.setTessellate(true);
     531  placemark.setGeometry(lineString);
     532
     533  //set the style
     534  var style = this.createStyle_(polyline);
     535  placemark.setStyleSelector(style);
     536
     537  var coords = lineString.getCoordinates();
     538  var path = polyline.getPath().getArray();
     539  //TODO(jlivni) use getPaths for case of multiple rings
     540  for (var i = 0, latLng; latLng = path[i]; i++) {
     541    coords.pushLatLngAlt(latLng.lat(), latLng.lng(), 0);
     542  }
     543
     544  ge.getFeatures().appendChild(placemark);
     545};
     546
     547/**
     548 * @param {google.maps.MVCObject} overlay the map overlay.
     549 * @return {google.earth.KmlStyle} the style.
     550 * @private
     551 */
     552GoogleEarth.prototype.createStyle_ = function(overlay) {
     553  var style = this.instance_.createStyle('');
     554  var polyStyle = style.getPolyStyle();
     555  var lineStyle = style.getLineStyle();
     556
     557  lineStyle.setWidth(this.getMVCVal_(overlay, 'strokeWeight', 3));
     558
     559  var strokeOpacity = this.getMVCVal_(overlay, 'strokeOpacity', 1);
     560  var fillOpacity = this.getMVCVal_(overlay, 'fillOpacity', 0.3);
     561  var strokeColor = this.getMVCVal_(overlay, 'strokeColor', '#000000');
     562  var fillColor = this.getMVCVal_(overlay, 'fillColor', '#000000');
     563
     564  lineStyle.getColor().set(GoogleEarth.getKMLColor_(strokeColor,
     565                                                   strokeOpacity));
     566  polyStyle.getColor().set(GoogleEarth.getKMLColor_(fillColor, fillOpacity));
     567
     568  return style;
     569};
     570
     571/**
     572 * Gets the property value from an mvc object.
     573 * @param {google.maps.MVCObject} mvcObject The object.
     574 * @param {string} property The property.
     575 * @param {string|number} def The default.
     576 * @return {string|number} The property, or default if property undefined.
     577 * @private
     578 */
     579GoogleEarth.prototype.getMVCVal_ = function(mvcObject, property, def) {
     580  var val = mvcObject.get(property);
     581  if (typeof val == 'undefined') {
     582    return def;
     583  } else {
     584    return /** @type {string|number} */(val);
     585  }
     586};
     587
     588/**
     589 * Add  map overlays to Earth.
     590 * @private
     591 */
     592GoogleEarth.prototype.addMapOverlays_ = function() {
     593  var overlays = this.getOverlays_();
     594  for (var i = 0, marker; marker = overlays['Marker'][i]; i++) {
     595    this.createPoint_(marker);
     596  }
     597  for (var i = 0, polygon; polygon = overlays['Polygon'][i]; i++) {
     598    this.createPolygon_(polygon);
     599  }
     600  for (var i = 0, polyline; polyline = overlays['Polyline'][i]; i++) {
     601    this.createPolyline_(polyline);
     602  }
     603  for (var i = 0, rectangle; rectangle = overlays['Rectangle'][i]; i++) {
     604    this.createRectangle_(rectangle);
     605  }
     606  for (var i = 0, circle; circle = overlays['Circle'][i]; i++) {
     607    this.createCircle_(circle);
     608  }
     609  for (var i = 0, kml; kml = overlays['KmlLayer'][i]; i++) {
     610    this.addKML_(kml.getUrl());
     611  }
     612  for (var i = 0, overlay; overlay = overlays['GroundOverlay'][i]; i++) {
     613    this.addGroundOverlay_(overlay);
     614  }
     615};
     616
     617/**
     618 * @private
     619 */
     620GoogleEarth.prototype.initializeEarth_ = function() {
     621  var that = this;
     622  google.earth.createInstance(this.earthDiv_, function(instance) {
     623    that.instance_ = /** @type {google.earth.GEPlugin} */(instance);
     624    that.addEarthEvents_();
     625    that.refresh_();
     626  }, function(e) {
     627    that.hideEarth_();
     628    //TODO(jlivni) record previous maptype
     629    that.map_.setMapTypeId(google.maps.MapTypeId.ROADMAP);
     630    throw 'Google Earth API failed to initialize: ' + e;
     631  });
     632};
     633
     634/**
     635 * @private
     636 */
     637GoogleEarth.prototype.addEarthEvents_ = function() {
     638  var ge = this.instance_;
     639  ge.getWindow().setVisibility(true);
     640
     641  // add a navigation control
     642  var navControl = ge.getNavigationControl();
     643  navControl.setVisibility(ge.VISIBILITY_AUTO);
     644
     645  var screen = navControl.getScreenXY();
     646  screen.setYUnits(ge.UNITS_INSET_PIXELS);
     647  screen.setXUnits(ge.UNITS_PIXELS);
     648
     649  // add some layers
     650  var layerRoot = ge.getLayerRoot();
     651  layerRoot.enableLayerById(ge.LAYER_BORDERS, true);
     652  layerRoot.enableLayerById(ge.LAYER_ROADS, true);
     653
     654  var that = this;
     655  google.maps.event.addListener(this.map_,
     656                                GoogleEarth.INFO_WINDOW_OPENED_EVENT_,
     657                                function(infowindow) {
     658    //If Earth is open, create balloon
     659    if (!that.earthVisible_) {
     660      return;
     661    }
     662    var balloon = that.instance_.createHtmlStringBalloon('');
     663    //TODO assuming anchor == marker == lastclicked
     664    var placemark = that.lastClickedPlacemark_;
     665    balloon.setFeature(placemark);
     666    balloon.setContentString(infowindow.getContent());
     667    that.instance_.setBalloon(balloon);
     668  });
     669
     670   // On click of a placemark we want to trigger the map click event.
     671  google.earth.addEventListener(ge.getGlobe(), 'click', function(event) {
     672    var target = event.getTarget();
     673    var overlay = that.overlays_[target.getId()];
     674    if (overlay) {
     675      event.preventDefault();
     676      // Close any currently opened map info windows.
     677      var infoWindows = that.getOverlaysForType_('InfoWindow');
     678      for (var i = 0, infoWindow; infoWindow = infoWindows[i]; i++) {
     679        infoWindow.close();
     680      }
     681      that.lastClickedPlacemark_ = target;
     682      google.maps.event.trigger(overlay, 'click');
     683    }
     684  });
     685
     686};
     687
     688/**
     689 * Set the Map view to match Earth.
     690 * @private
     691 */
     692GoogleEarth.prototype.matchMapToEarth_ = function() {
     693  var lookAt = this.instance_.getView().copyAsLookAt(
     694      this.instance_.ALTITUDE_RELATIVE_TO_GROUND);
     695  var range = lookAt.getRange();
     696  var zoom = Math.round(
     697      GoogleEarth.MAX_EARTH_ZOOM_ - (Math.log(range) / Math.log(2)));
     698  if (!this.map_.getZoom() == zoom) {
     699    this.map_.setZoom(zoom - 1);
     700  } else {
     701    this.map_.setZoom(zoom);
     702  }
     703  var center = new google.maps.LatLng(lookAt.getLatitude(),
     704                                      lookAt.getLongitude());
     705  this.map_.panTo(center);
     706};
     707
     708/**
     709 * Animate from Earth to Maps view.
     710 * @private
     711 */
     712GoogleEarth.prototype.switchToMapView_ = function() {
     713  if (!this.earthVisible_) {
     714    return;
     715  }
     716
     717  // First, set map to match current earth view.
     718  this.matchMapToEarth_();
     719
     720  // Now fly Earth to match the map view.
     721  var that = this;
     722
     723  window.setTimeout(function() {
     724    // Sometimes it takes a few ms before the map zoom is ready.
     725    that.flyToMapView_();
     726  }, 50);
     727
     728  window.setTimeout(function() {
     729    // And switch back to maps once we've flown.
     730    that.hideEarth_();
     731  }, 2200);
     732};
     733
     734/**
     735 * Hide the Earth div.
     736 * @private
     737 */
     738GoogleEarth.prototype.hideEarth_ = function() {
     739  this.unsetZIndexes_();
     740  this.removeShim_();
     741
     742  this.controlDiv_.style.display = 'none';
     743  this.earthVisible_ = false;
     744};
     745
     746/**
     747 * Sets the z-index of all controls except for the map type control so that
     748 * they appear behind Earth.
     749 * @param {Node} mapTypeControlDiv the control div.
     750 * @private
     751 */
     752GoogleEarth.prototype.setZIndexes_ = function(mapTypeControlDiv) {
     753  var oldIndex = mapTypeControlDiv.style.zIndex;
     754  var siblings = this.controlDiv_.parentNode.childNodes;
     755  for (var i = 0, sibling; sibling = siblings[i]; i++) {
     756    sibling['__gme_ozi'] = sibling.style.zIndex;
     757    // Sets the zIndex of all controls to be behind Earth.
     758    sibling.style.zIndex = -1;
     759  }
     760
     761  mapTypeControlDiv['__gme_ozi'] = oldIndex;
     762  this.controlDiv_.style.zIndex = mapTypeControlDiv.style.zIndex = 0;
     763};
     764
     765/**
     766 * @private
     767 */
     768GoogleEarth.prototype.unsetZIndexes_ = function() {
     769  var siblings = this.controlDiv_.parentNode.childNodes;
     770  for (var i = 0, sibling; sibling = siblings[i]; i++) {
     771    // Set the old zIndex back
     772    sibling.style.zIndex = sibling['__gme_ozi'];
     773  }
     774};
     775
     776/**
     777 * @param {Node} mapTypeControlDiv the control div.
     778 * @private
     779 */
     780GoogleEarth.prototype.addShim_ = function(mapTypeControlDiv) {
     781  var iframeShim = this.iframeShim_ = document.createElement('IFRAME');
     782  iframeShim.src = 'javascript:false;';
     783  iframeShim.scrolling = 'no';
     784  iframeShim.frameBorder = '0';
     785
     786  var style = iframeShim.style;
     787  style.zIndex = -100000;
     788  style.width = style.height = '100%';
     789  style.position = 'absolute';
     790  style.left = style.top = 0;
     791
     792  // Appends the iframe to the map type control's DIV so that its width and
     793  // height will be 100% and if the control changes from a bar to a drop down,
     794  // it flows nicely.
     795  mapTypeControlDiv.appendChild(iframeShim);
     796};
     797
     798/**
     799 * Remove the shim containing the earth div.
     800 * @private
     801 */
     802GoogleEarth.prototype.removeShim_ = function() {
     803  this.iframeShim_.parentNode.removeChild(this.iframeShim_);
     804  this.iframeShim_ = null;
     805};
     806
     807/**
     808 * @private
     809 * @return {Node} the map type control div.
     810 */
     811GoogleEarth.prototype.findMapTypeControlDiv_ = function() {
     812  var title = 'title=[\'\"]?' + this.earthTitle_ + '[\"\']?';
     813  var regex = new RegExp(title);
     814  var siblings = this.controlDiv_.parentNode.childNodes;
     815  for (var i = 0, sibling; sibling = siblings[i]; i++) {
     816    if (regex.test(sibling.innerHTML)) {
     817      return sibling;
     818    }
     819  }
     820};
     821
     822/**
     823 * @private
     824 */
     825GoogleEarth.prototype.addEarthControl_ = function() {
     826  var mapDiv = this.mapDiv_;
     827
     828  var control = this.controlDiv_ = document.createElement('DIV');
     829  control.style.position = 'absolute';
     830  control.style.width = 0;
     831  control.style.height = 0;
     832  control.index = 0;
     833  control.style.display = 'none';
     834
     835  var inner = this.innerDiv_ = document.createElement('DIV');
     836  inner.style.width = mapDiv.clientWidth + 'px';
     837  inner.style.height = mapDiv.clientHeight + 'px';
     838  inner.style.position = 'absolute';
     839
     840  control.appendChild(inner);
     841
     842  var earthDiv = this.earthDiv_ = document.createElement('DIV');
     843  earthDiv.style.position = 'absolute';
     844  earthDiv.style.width = '100%';
     845  earthDiv.style.height = '100%';
     846
     847  inner.appendChild(earthDiv);
     848
     849  this.map_.controls[google.maps.ControlPosition.TOP_LEFT].push(control);
     850
     851  var that = this;
     852
     853  google.maps.event.addListener(this.map_, 'resize', function() {
     854    that.resizeEarth_();
     855  });
     856};
     857
     858/**
     859 * @private
     860 */
     861GoogleEarth.prototype.resizeEarth_ = function() {
     862  var innerStyle = this.innerDiv_.style;
     863  var mapDiv = this.mapDiv_;
     864  innerStyle.width = mapDiv.clientWidth + 'px';
     865  innerStyle.height = mapDiv.clientHeight + 'px';
     866};
     867
     868/**
     869 * @param {string} type type of overlay (Polygon, etc).
     870 * @return {Array.<Object>} list of overlays of given type currently on map.
     871 * @private
     872 */
     873GoogleEarth.prototype.getOverlaysForType_ = function(type) {
     874  var tmp = [];
     875  var overlays = GoogleEarth.overlays_[type];
     876  for (var i in overlays) {
     877    if (overlays.hasOwnProperty(i)) {
     878      var overlay = overlays[i];
     879      if (overlay.get('map') == this.map_) {
     880        tmp.push(overlay);
     881      }
     882    }
     883  }
     884  return tmp;
     885};
     886
     887/**
     888 * @return {Object} dictionary of lists for all map overlays.
     889 * @private
     890 */
     891GoogleEarth.prototype.getOverlays_ = function() {
     892  var overlays = {};
     893  var overlayClasses = GoogleEarth.OVERLAY_CLASSES;
     894
     895  for (var i = 0, overlayClass; overlayClass = overlayClasses[i]; i++) {
     896    overlays[overlayClass] = this.getOverlaysForType_(overlayClass);
     897  }
     898  return overlays;
     899};
     900
     901/**
     902 * @private
     903 */
     904GoogleEarth.overlays_ = {};
     905
     906/**
     907 * override the open property for infowindow
     908 * @private
     909 */
     910GoogleEarth.modifyOpen_ = function() {
     911  google.maps.InfoWindow.prototype.openOriginal_ =
     912      google.maps.InfoWindow.prototype['open'];
     913
     914  GoogleEarth.overlays_['InfoWindow'] = {};
     915  google.maps.InfoWindow.prototype['open'] = function(map, anchor) {
     916    if (map) {
     917      if (!this['__gme_id']) {
     918        this['__gme_id'] = GoogleEarth.counter_++;
     919        GoogleEarth.overlays_['InfoWindow'][this['__gme_id']] = this;
     920      }
     921    } else {
     922      delete GoogleEarth.overlays_['InfoWindow'][this['__gme_id']];
     923      this['__gme_id'] = undefined;
     924    }
     925    google.maps.event.trigger(map, GoogleEarth.INFO_WINDOW_OPENED_EVENT_, this);
     926    this.openOriginal_(map, anchor);
     927  };
     928};
     929
     930/**
     931 * @param {string} overlayClass overlay type, such as Marker, Polygon, etc.
     932 * @private
     933 */
     934GoogleEarth.modifySetMap_ = function(overlayClass) {
     935  var proto = google.maps[overlayClass].prototype;
     936  proto['__gme_setMapOriginal'] = proto.setMap;
     937
     938  GoogleEarth.overlays_[overlayClass] = {};
     939  google.maps[overlayClass].prototype['setMap'] = function(map) {
     940    if (map) {
     941      if (!this['__gme_id']) {
     942        this['__gme_id'] = GoogleEarth.counter_++;
     943        GoogleEarth.overlays_[overlayClass][this['__gme_id']] = this;
     944      }
     945    } else {
     946      delete GoogleEarth.overlays_[overlayClass][this['__gme_id']];
     947      this['__gme_id'] = undefined;
     948    }
     949
     950    this['__gme_setMapOriginal'](map);
     951  };
     952};
     953
     954/**
     955 * @const
     956 * @type {Array.<string>}
     957 */
     958GoogleEarth.OVERLAY_CLASSES = ['Marker', 'Polyline', 'Polygon', 'Rectangle',
     959    'Circle', 'KmlLayer', 'GroundOverlay', 'InfoWindow'];
     960
     961/**
     962 * Keep track of total number of placemarks added.
     963 * @type {number}
     964 * @private
     965 */
     966GoogleEarth.counter_ = 0;
     967
     968/**
     969 * Wrapper to call appropriate prototype override methods for all overlays
     970 * @private
     971 */
     972GoogleEarth.trackOverlays_ = function() {
     973  var overlayClasses = GoogleEarth.OVERLAY_CLASSES;
     974
     975  for (var i = 0, overlayClass; overlayClass = overlayClasses[i]; i++) {
     976    GoogleEarth.modifySetMap_(overlayClass);
     977    if (overlayClass == 'InfoWindow') {
     978      GoogleEarth.modifyOpen_();
     979    }
     980  }
     981};
     982
     983GoogleEarth.trackOverlays_();
  • _plugins_/gmap/trunk/mapimpl/gma3/public/script_init.php

    r53465 r54783  
    4242                $out .= '//]]>'."\n".'</script>'."\n";
    4343       
    44                 // Plugin google earth (http://google-maps-utility-library-v3.googlecode.com/svn/trunk/googleearth/)
     44                // Plugin google earth
     45                // Avec bonne volonté, je voudrais bien utiliser directement le js des librairies, mais il
     46                // y a un bug (connu) sur les marqueurs customisés, donc ça ne marche pas, alors je
     47                // le corrige et garde une version locale...
     48//              $earth = "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/googleearth/src/googleearth-compiled.js";
    4549                $earth = find_in_path('mapimpl/gma3/javascript/googleearth.js');
    4650                $out .= '<script type="text/javascript" src="'.$earth.'"></script>'."\n";
Note: See TracChangeset for help on using the changeset viewer.