xkjyeah / vue-google-maps

Google maps component for vue with 2-way data binding
https://xkjyeah.github.io/vue-google-maps/
1.88k stars 475 forks source link

Use with heatmap #130

Open marcoprodata opened 7 years ago

marcoprodata commented 7 years ago

Its possible to use this with heatmap?

xkjyeah commented 7 years ago

Yes... but I don't have an example right now. The method used is similar to that here:

http://xkjyeah.github.io/vue-google-maps/overlay.html

marcoprodata commented 7 years ago

I need this https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap?hl=pt-br

That feature "heatmaplayer" is possible to use with this plugin?

Sorry for my bad english

xkjyeah commented 7 years ago

Ok, produce some sample data for me, please, and I'll see what I can do about it. No promises or timeline, though

On 9 Jun 2017 01:19, "marcoprodata" notifications@github.com wrote:

I need this https://developers.google.com/maps/documentation/javascript/ examples/layer-heatmap?hl=pt-br

That feature "heatmaplayer" is possible to use with this plugin?

Sorry for my bad english

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/xkjyeah/vue-google-maps/issues/130#issuecomment-307170029, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiTR87lw1cZFqg113kCXw7-32ZIWZqIks5sCC0pgaJpZM4N0Jt6 .

ikashifullah commented 6 years ago

@xkjyeah, @marcoprodata any progress on this?

Aterr commented 6 years ago

Same problems here. Any info would be very helpful.

prestanesia commented 6 years ago

Heres my code to display heatmaps :

Vue.use(VueGoogleMaps, {
  load: {
    key: your-key',
    libraries: 'visualization',
  }
})

Please note that getheatmap endpoint is only returning array of lat and lng

  mounted () {
      this.$nextTick(() => {
        this.$refs.mymap.$mapCreated.then(() => {
          var self = this;
          Http.post("v1/getheatmap")
          .then(response => {
            let latlon = new google.maps.MVCArray();
            response.data.result.forEach(function(coord) {
                latlon.push(new google.maps.LatLng(coord.lat, coord.lng));
            });
            let x = new google.maps.visualization.HeatmapLayer({
              data: latlon,
              map: self.$refs.mymap.$mapObject
            });            
          })
        })
    })
  }
Aterr commented 6 years ago

@prestanesia worked for me! Thanks a lot!

xkjyeah commented 6 years ago

Hey all, I've tried to write a function to help devs create Vue components that map to an underlying Google Maps component.

This is available from version 0.9.0. (note: there are some API changes from v0.8.x -- in particular, $mapCreated has been renamed $mapPromise for consistency with the other components)

Something like this should work: (Note: I don't intend to support Heatmap directly in this library, hence I'm not creating the components for it. I will maintain the helper function though, and it's probably straightforward enough to wrap around any component you wish to use)

// HeatmapLayer.js
import {MapElementFactory} from 'vue2-google-maps'

export default MapElementFactory({
  name: 'heatmapLayer',
  ctr: () => google.maps.visualization.HeatmapLayer,
  events: [],
  mappedProps: {
    data: {type: Object},
    options: {type: Object},
  }
})
hkd987 commented 6 years ago

Where are you bringing in the google variable with your helper function?

xkjyeah commented 6 years ago

The helper function initializes the component only after the map has been loaded, so 'Google' is already available as a global.

Ctr is a function so that you won't get a Google is undefined error

estebancores commented 6 years ago

Hello, y hope all of you be fine, y use this solution for heatmaps

mounted () { this.$nextTick(() => { this.$refs.mymap.$mapCreated.then(() => { var self = this; Http.post("v1/getheatmap") .then(response => { let latlon = new google.maps.MVCArray(); response.data.result.forEach(function(coord) { latlon.push(new google.maps.LatLng(coord.lat, coord.lng)); }); let x = new google.maps.visualization.HeatmapLayer({ data: latlon, map: self.$refs.mymap.$mapObject });
}) }) }) }

the problem now its that i need to clean de heatlayer to put new coords but im still looking for an solution. @prestanesia how can you do that?

rafafreitas commented 5 years ago

Sorry for my English... I created an example to facilitate future searches.

It was based on the project: https://www.npmjs.com/package/vue-google-heatmap

but using the vue-google-maps.

I hope this can help someone.

// main.js

import * as VueGoogleMaps from 'vue2-google-maps'

Vue.use(VueGoogleMaps, {
  load: {
    key: "#############",
    libraries: ["places", "visualization"]
  }
})
// HeatMap.vue

<template>
  <div
    ref="heatmap"
    :style="`width: ${mapWidth}; height: ${mapHeight}`"/>
</template>

<script>
export default {
  name: 'c-heat-map',
  props: {
    lat: {
      type: Number,
      default: () => 37.775
    },
    lng: {
      type: Number,
      default: () => -122.434
    },
    initialZoom: {
      type: Number,
      default: () => 13
    },
    mapType: {
      type: String,
      default: () => 'roadmap'
    },
    points: {
      type: Array,
      required: true
    },
    width: {
      type: [String, Number],
      default: () => '100%'
    },
    height: {
      type: [String, Number],
      default: () => '100%'
    },
    opacity: {
      type: Number,
      default: () => 1
    },
    maxIntensity: {
      type: Number,
      default: () => 5
    }
  },
  computed: {
    mapWidth () {
      if (typeof this.width === 'string') {
        return this.width
      } else {
        return `${this.width}px`
      }
    },
    mapHeight () {
      if (typeof this.height === 'string') {
        return this.height
      } else {
        return `${this.height}px`
      }
    },
    heatmapPoints () {
      return this.points.map(
        // eslint-disable-next-line
          point => new google.maps.LatLng(point.lat, point.lng)
      )
    }
  },
  mounted () {
    return this.$gmapApiPromiseLazy().then(() => {
      // eslint-disable-next-line
        this.$mapObject = new google.maps.Map(this.$refs.heatmap, {
        zoom: this.initialZoom,
        center: { lat: this.lat, lng: this.lng },
        mapTypeId: this.mapType
      })
      // eslint-disable-next-line
        this.$heatmap = new google.maps.visualization.HeatmapLayer({
        data: this.heatmapPoints,
        map: this.$mapObject,
        opacity: this.opacity,
        maxIntensity: this.maxIntensity
      })

      this.$heatmap.setMap(this.$mapObject)
    })
  }
}
</script>
// Page

<template>
  <heat-map
    :points="data"
    :lat="parseFloat(getCenterMap.lat)"
    :lng="parseFloat(getCenterMap.lng)"
    :width="600"
    :height="500"
  />
</template>

<script>
import HeatMap from '@/components/HeatMap'

export default {
  name: 'view-page',
  components: { HeatMap },
  data: () => {
    return {
      data: [
        {lat: 37.786117, lng:-122.440119},
        {lat: 37.786564, lng:-122.440209},
        {lat: 37.786905, lng:-122.440270},
        {lat: 37.786956, lng:-122.440279},
        {lat: 37.800224, lng:-122.433520},
        {lat: 37.800155, lng:-122.434101},
        {lat: 37.800160, lng:-122.434430},
        {lat: 37.800378, lng:-122.434527},
        {lat: 37.800738, lng:-122.434598},
        {lat: 37.800938, lng:-122.434650},
        {lat: 37.801024, lng:-122.434889},
        {lat: 37.800955, lng:-122.435392},
        {lat: 37.800886, lng:-122.435959}
      ]
    }
  },
  methods: {
    getCenterMap () {
      return {
    lat: this.data[this.data.length - 1].lat,
        lng: this.data[this.data.length - 1].lng
      }
    }
  }
}
</script>
aruisan commented 5 years ago

man i need to include a weight to the arrays something like this: var heatMapData = [ {location: new google.maps.LatLng(37.782, -122.447), weight: 0.5}, new google.maps.LatLng(37.782, -122.445), {location: new google.maps.LatLng(37.782, -122.443), weight: 2}, {location: new google.maps.LatLng(37.782, -122.441), weight: 3}, {location: new google.maps.LatLng(37.782, -122.439), weight: 2}, new google.maps.LatLng(37.782, -122.437), {location: new google.maps.LatLng(37.782, -122.435), weight: 0.5},

{location: new google.maps.LatLng(37.785, -122.447), weight: 3}, {location: new google.maps.LatLng(37.785, -122.445), weight: 2}, new google.maps.LatLng(37.785, -122.443), {location: new google.maps.LatLng(37.785, -122.441), weight: 0.5}, new google.maps.LatLng(37.785, -122.439), {location: new google.maps.LatLng(37.785, -122.437), weight: 2}, {location: new google.maps.LatLng(37.785, -122.435), weight: 3} ];

alecat88 commented 5 years ago

So, did somebody succeeded to do a Heatmap and maybe provide a fiddle for it?

@prestanesia do you mind sharing a fiddle since your solutions seem the most loved please?

timmaier commented 5 years ago

Sorry for my English... I created an example to facilitate future searches.

It was based on the project: https://www.npmjs.com/package/vue-google-heatmap

but using the vue-google-maps.

I hope this can help someone.

// main.js

import * as VueGoogleMaps from 'vue2-google-maps'

Vue.use(VueGoogleMaps, {
  load: {
    key: "#############",
    libraries: ["places", "visualization"]
  }
})
// HeatMap.vue

<template>
  <div
    ref="heatmap"
    :style="`width: ${mapWidth}; height: ${mapHeight}`"/>
</template>

<script>
export default {
  name: 'c-heat-map',
  props: {
    lat: {
      type: Number,
      default: () => 37.775
    },
    lng: {
      type: Number,
      default: () => -122.434
    },
    initialZoom: {
      type: Number,
      default: () => 13
    },
    mapType: {
      type: String,
      default: () => 'roadmap'
    },
    points: {
      type: Array,
      required: true
    },
    width: {
      type: [String, Number],
      default: () => '100%'
    },
    height: {
      type: [String, Number],
      default: () => '100%'
    },
    opacity: {
      type: Number,
      default: () => 1
    },
    maxIntensity: {
      type: Number,
      default: () => 5
    }
  },
  computed: {
    mapWidth () {
      if (typeof this.width === 'string') {
        return this.width
      } else {
        return `${this.width}px`
      }
    },
    mapHeight () {
      if (typeof this.height === 'string') {
        return this.height
      } else {
        return `${this.height}px`
      }
    },
    heatmapPoints () {
      return this.points.map(
        // eslint-disable-next-line
          point => new google.maps.LatLng(point.lat, point.lng)
      )
    }
  },
  mounted () {
    return this.$gmapApiPromiseLazy().then(() => {
      // eslint-disable-next-line
        this.$mapObject = new google.maps.Map(this.$refs.heatmap, {
        zoom: this.initialZoom,
        center: { lat: this.lat, lng: this.lng },
        mapTypeId: this.mapType
      })
      // eslint-disable-next-line
        this.$heatmap = new google.maps.visualization.HeatmapLayer({
        data: this.heatmapPoints,
        map: this.$mapObject,
        opacity: this.opacity,
        maxIntensity: this.maxIntensity
      })

      this.$heatmap.setMap(this.$mapObject)
    })
  }
}
</script>
// Page

<template>
  <heat-map
    :points="data"
    :lat="parseFloat(getCenterMap.lat)"
    :lng="parseFloat(getCenterMap.lng)"
    :width="600"
    :height="500"
  />
</template>

<script>
import HeatMap from '@/components/HeatMap'

export default {
  name: 'view-page',
  components: { HeatMap },
  data: () => {
    return {
      data: [
        {lat: 37.786117, lng:-122.440119},
        {lat: 37.786564, lng:-122.440209},
        {lat: 37.786905, lng:-122.440270},
        {lat: 37.786956, lng:-122.440279},
        {lat: 37.800224, lng:-122.433520},
        {lat: 37.800155, lng:-122.434101},
        {lat: 37.800160, lng:-122.434430},
        {lat: 37.800378, lng:-122.434527},
        {lat: 37.800738, lng:-122.434598},
        {lat: 37.800938, lng:-122.434650},
        {lat: 37.801024, lng:-122.434889},
        {lat: 37.800955, lng:-122.435392},
        {lat: 37.800886, lng:-122.435959}
      ]
    }
  },
  methods: {
    getCenterMap () {
      return {
  lat: this.data[this.data.length - 1].lat,
      lng: this.data[this.data.length - 1].lng
      }
    }
  }
}
</script>

This works great. I found a small bug that made it not run for me. Had to change:

:lat="parseFloat(getCenterMap.lat)"
:lng="parseFloat(getCenterMap.lng)"

to

  :lat="getCenterMap().lat"
  :lng="getCenterMap().lng"

I also needed weighting for the heatmap points so I changed:

point => new google.maps.LatLng(point.lat, point.lng)

to

function (point) {
    return { location: new google.maps.LatLng(point.lat, point.lng), weight: point.weight }
}

which lets me pass weighted data like so:

data: [
    {lat: 37.786117, lng:-122.440119, weight: 0.5},
    {lat: 37.800886, lng:-122.435959, weight: 3}
]
jaykumar17 commented 4 years ago

I have more than 10000 data (lat and long. But when I get data on heatmap. i dont getting all data on map. so how to solve this problem. please give me proper solution. below my code <vue-google-heatmap v-if="points.length" :initial-zoom=7.8 :lat=52.379189 :lng=4.899431 :radius=40 :points="points"

getPoints () {
axios.get("/fetch-heatmaps-points",{params: {ID: this.$route.params.id}}) .then(response => {
if(response.data.total_record > 0) { this.points = response.data.response; } else { this.points=[{lat:52.379189, lng:4.899431}]; }
}) },

pealthoff commented 2 years ago

Hi @rafafreitas and @timmaier, thanks for your solutions

I also included a "options" prop on the component:

// HeatMap.vue
// ...
props: {
// ...
options: {
      type: Object,
    }
// ...
//Page.vue

// ...

<HeatMap
    v-if="loaded"
    style="width: 100vw"
    class="fill-height"
    :points="points"
    :lat="center.lat"
    :lng="center.lng"
    :initial-zoom="zoom"
    :options="{
        zoomControl: true,
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        rotateControl: false,
        fullscreenControl: true,
        disableDefaultUi: false,
    }"
        />
// ...