GoogleWebComponents / google-map

Google Maps web components
https://elements.polymer-project.org/elements/google-map
Other
438 stars 257 forks source link

fit-to-marker no longer correctly centers map on search updates #301

Open ghost opened 8 years ago

ghost commented 8 years ago

Hi there,

I'm trying to implement google-map, google-map-marker and google -map-search

<google-map-search global-search="true" map="{{map}}" query="{{searchPlace}}" results="{{results}}"></google-map-search>

<google-map map="{{map}}" api-key="XXX" fit-to-markers>
      <template is="dom-repeat" items="{{results}}" as="marker">
        <google-map-marker latitude="{{marker.latitude}}" longitude="{{marker.longitude}}">
          <h2>{{marker.name}}</h2>
          <span>{{marker.formatted_address}}</span>
        </google-map-marker>
      </template>
</google-map>

When launching a first search on a place, I juste do :

this.searchPlace = <my search>;

And after that, the map update his center to focus on the marker, but if I do another search immediatly, the marker update his position, but the map stay with the same center. Should I do something specific after/before performing a search to be sure that the center of the map is updated?

thanks

ghost commented 8 years ago

Update :

Another question about the image. I've seen an new element like this one each time i perfom a search, what is it?

<div draggable="false" class="gm-style-cc" style="-webkit-user-select: none; height: 14px; line-height: 14px; z-index: 0; position: absolute; bottom: 127px; right: 0px;"><div style="opacity: 0.7; width: 100%; height: 100%; position: absolute;"><div style="width: 1px;"></div><div style="width: auto; height: 100%; margin-left: 1px; background-color: rgb(245, 245, 245);"></div></div><div style="position: relative; padding-right: 6px; padding-left: 6px; font-family: Roboto, Arial, sans-serif; font-size: 10px; color: rgb(68, 68, 68); white-space: nowrap; direction: ltr; text-align: right; vertical-align: middle; display: inline-block; padding-bottom: 0px;"></div></div>

map

ebidel commented 8 years ago

I believe you should also data bind latitude/longitude on the map element itself (e.g set it to the lat/lng of one of the marker results).

ghost commented 8 years ago

Yep, it's seem working, but to be honest I don't really understand ... The code I provided is not complete, here is the "full" version

    <google-map-search global-search="true" map="[[map]]" query="{{searchPlace}}" results="{{results}}"></google-map-search>

    <google-map map="{{map}}" api-key="XXX" fit-to-markers>

      <template id="sitesRepeat" is="dom-repeat" items="{{sitesMarkers}}" as="marker">
        <google-map-marker latitude="{{marker.lat}}" longitude="{{marker.long}}" title="{{marker.title}}"></google-map-marker>
      </template>

      <template is="dom-repeat" items="{{resultsMarker}}" as="marker">
        <google-map-marker latitude="{{marker.lat}}" longitude="{{marker.long}}" title="{{marker.title}}">
          <h2>{{marker.name}}</h2>
          <span>{{marker.formatted_address}}</span>
        </google-map-marker>
      </template>

    </google-map>

As you see I don't have only one dom-repeat, but two (for the moment, at the end it will be 4 dom-repeat)

For the one which use the sitesMarkers variables, here the function which fill the array

_onSiteUpdate : function _onSiteUpdate (evt) {
        var sites = evt.detail,
            i = sites.length,
            // clone
            tmpSitesArr = _.clone(this.sitesMarkers, true);

        while (i--) {
          // on regarde s'il existe, et son index si oui
          var index = _.findIndex(tmpSitesArr, function (s) {
            return s.siteId == sites[i].id
          });

          if (sites[i].add) {
            // ajout, et un index existe, mise à jour 
            if (index != -1) {
              tmpSitesArr[index] = {
                "lat" : sites[i].position.y,
                "long" : sites[i].position.x,
                "title" : sites[i].name
              };
            } else {
              // ajout, mais pas d'index, création
              tmpSitesArr.push({
                "lat" : sites[i].position.y,
                "long" : sites[i].position.x,
                "title" : sites[i].name
              });
            }
          } else {
            // suppression, et un index existe, on supprime 
            if (index != -1) {
              tmpSitesArr.splice(index, 1);
            }
          }
        }
        this.set("sitesMarkers", tmpSitesArr);
      },

With this function, each time I update my sitesMarkers array, the map will always update his center, without doing anything. But not with the search results, and I really don't understand what's the difference.

I try to build the "same" function for the results, but without the lat/long binding on the map, the problem stay here

_onSearchResult : function _onSearchResult (evt) {
        var results = evt.detail,
            i = results.length,
            tmpArr = [];

        this.set("resultsMarker", []);

        while (i--) {
          tmpArr.push({
            "lat" : results[i].latitude,
            "long" : results[i].longitude,
            "title" : results[i].name
          });
        }

        this.set("resultsMarker", tmpArr);
      },

What's the difference? Thanks a lot

ebidel commented 8 years ago

Actually, I see you're using fit-to-markers, which means the map should update it's center automatically. No need to set the lat/lng or (data bind them) explicitly.

Hmm, http://jsbin.com/vaqocuvagu/edit?html,output updates for me.

ghost commented 8 years ago

Sorry for the long answer ...

The problem is here on your jsbin too

With the pre-filled value "pizza" it works. Search for "paris" after that, it works too. Search for "tokyo" and marker is updated, but not the map center.

But if you launch another search for (again) "pizza", the map center will update

ebidel commented 8 years ago

I see. Yea, that does repo for me. Thanks for posting the steps.

motss commented 8 years ago

Not working in Shadow DOM either.

ghost commented 7 years ago

Any news about this issue?

ghost commented 7 years ago

up !

dwalters18 commented 7 years ago

@bastienarm Not the most elegant work-around, but this should help

ready() {
  this.addEventListener('google-map-search-results', e => this._updateCenter(e));
}

/**
  * Update the map center on search result changes
  * @param e
  * @private
  */
_updateCenter(e) {
  let $map = this.$$("google-map");
  if ($map) {
    this.async(() => {
      if ($map.fitToMarkers) {
        $map._fitToMarkersChanged();
      } else {
        $map._updateCenter();
      }
    }, 30);
  }
}