ionic-team / ionic-native-google-maps

Google maps plugin for Ionic Native
Other
221 stars 125 forks source link

WebGl Markers Question #340

Open stevebrowndotco opened 3 years ago

stevebrowndotco commented 3 years ago

I'm submitting a ... (check one with "x")

Hello, I was just wondering if anyone has succeeded in adding WebGl markers to the Ionic Native Google map.

WebGl is useful because it allows to add millions of markers with little performance hit, since it uses the GPU each marker is not rendered as a separate DOM element.

I have seen that this is possible with the javascript API, see here: https://github.com/ubilabs/google-maps-api-threejs-layer

They key part is this line: https://github.com/ubilabs/google-maps-api-threejs-layer/blob/master/threejs-layer.js#L44

They are using OverlayView from an instance of this.map (javascript API) to attach Three.Js particles to the map instance.

Is this possible with this plugin? To add WebGl markers?

Thank you

wf9a5m75 commented 3 years ago

Sorry, this plugin uses native google maps view on Android/iOS, not Google Maps JavaScript API v3. So, there is no way so far.

stevebrowndotco commented 3 years ago

Yes I know it's not the Javascript API but i'm wondering if there is a solution to this similar to the example I posted. This would be incredibly useful.

Effectively what we need to do is calculate the pixel co-ordinates of where to place a particle based on the original lat lng.

Google have their own example of such calculations here: https://developers.google.com/maps/documentation/javascript/examples/map-coordinates

// The mapping between latitude, longitude and pixels is defined by the web
// mercator projection.
function project(latLng: google.maps.LatLng) {
  let siny = Math.sin((latLng.lat() * Math.PI) / 180);

  // Truncating to 0.9999 effectively limits latitude to 89.189. This is
  // about a third of a tile past the edge of the world tile.
  siny = Math.min(Math.max(siny, -0.9999), 0.9999);

  return new google.maps.Point(
    TILE_SIZE * (0.5 + latLng.lng() / 360),
    TILE_SIZE * (0.5 - Math.log((1 + siny) / (1 - siny)) / (4 * Math.PI))
  );
}

But this is based on the tile size, rather than the map element size.

We have access to the getVisibleRegion() function, so that might be a good starting place...

I appreciate this is more of a discussion than a support request but it would be good to bounce ideas from others who are seeking the same... I'm surprised webGl markers haven't been asked here before actually because they are very popular with other map frameworks. I prefer to stick with ionic native googlemaps though because of the cached tile support..

stevebrowndotco commented 3 years ago

I think it's possible unless I can be proved wrong :)

stevebrowndotco commented 3 years ago

Another useful link is this answer here https://stackoverflow.com/a/12026134/523014

wf9a5m75 commented 3 years ago

Unfortunately I don't think this is possible. Because the map is not a HTML element.

If the marker on webgl is touched, the marker will response. But if the marker is not touched, then touch doesn't go to map view, because the map is not a HTML element.

wf9a5m75 commented 3 years ago

Detection of touch is only one chance, and only "browser" or "mapview" only.

Can not implement "browser (WebGL layer)" -> "map view"

stevebrowndotco commented 3 years ago

I understand what you mean, but my proposed "webGl layer" doesn't even know about Ionic Google Maps, but it can be fed the lat lng bounding box.

The pixels are drawn to a separate div element in the DOM, overlaid on top of the native google map element.

The map is not an HTML element, but the map container is.

If the map container is 100px by 100px, I have the width and height in pixels. If I can get the lat lng bounding box of the native map, which I think I can, then I should be able to calculate pixel co-ordinates of lat lng positions just like the previous examples.

I think.

wf9a5m75 commented 3 years ago

"webGl layer" indicates a canvas this time. So after touching canvas, the touch event goes to the map div. But the map div is empty. There is no map inside the map div. .

So, if you touch on Polygon, the touch will receive the canvas, that's why nothing happens.

Do you want to prefer this behavior?

wf9a5m75 commented 3 years ago

Even if you believe you can implement, please try to implement by yourself. All code is open, and if you archive, please send it as pull request. I'm happy to merge it.

wf9a5m75 commented 3 years ago

By the way, the native google maps view uses OpenGL, so, basically all drawing is rendered by GPU.

stevebrowndotco commented 3 years ago

"By the way, the native google maps view uses OpenGL, so, basically all drawing is rendered by GPU."

I'm experiencing slowness when rendering thousands of markers at once, either I am doing something wrong or it's the way that markers are rendered :/

"If the marker on webgl is touched, the marker will response. But if the marker is not touched, then touch doesn't go to map view, because the map is not a HTML element."

Yes I understand that this is the biggest limitation, we can't mix the webGl layer and the map layers together like you can with the js api, because it's native. I was thinking a solution could be to have pointer-events: none on the webGl layer, and the markers underneath would be transparent but it might bring back the sloweness.