visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.19k stars 2.09k forks source link

Deck.gl with Harp.gl map? #4529

Closed gallickgunner closed 4 years ago

gallickgunner commented 4 years ago

Hello, new to web based programming here. Just wanted to know if I can use deck.gl layers with the mapView provided by harp.gl.

I tried mixing these two, but found that you apparently need to synchronize the camera between deckgl and the map provider I guess. So in the example I coded, I couldn't move the harp.gl map once Deckgl's canvas was laid on top. It kept moving the deckgl map view and layers would show up but the underlying harpgl map canvas wasn't synchronized.

Can anybody tell me if it's doable with a little modification in deck.gl? If so where should I get started or what's the core part that I need to look at in order to get these two working together?

Pessimistress commented 4 years ago

You should check out how synchronization is done in the mapbox pure-js example. If I remember right harp.gl uses a different default FOV. deck.gl's FOV is Math.atan(1 / 3) * 2 ~= 36 degrees.

gallickgunner commented 4 years ago

Many thanks for the link to the example. I managed to find the proper functions in harpgl and did the same thing and it works. Will post the repository link in case anybody else is interested in the setup.

kylebarron commented 4 years ago

I think it would be helpful to see for future reference if someone new asks

gallickgunner commented 4 years ago

@kylebarron - Yeah sorry for the delay. I committed the fully working base code here, a little messy right now but let me elaborate the main part here.

So as Pessimistress linked, all you gotta do is first set the FOV correctly, then set the viewState parameters mainly the center, pitch, bearing and zoom level. I don't know why but it seems that we need to add "1" to the zoom level currently defined in deckgl's viewState prop to make it work with harp.gl's zoom parameter.

There were a couple of functions in harpgl that set the orientation, rotation etc but I got it working with lookAt. Also this may confuse some people but harpgl often uses the word tilt for the pitch angle. Similarly it uses heading/yaw for the bearing.

initMapView = () => {
   const viewState = this.state.viewState;
    this.mapView.setFovCalculation({fov: 36, type: 'fixed'}); // This sets the focalLength internally which we access during viewState change
    this.mapView.maxZoomLevel = 21;    

   // Initialize the MapView with your initial ViewState parameters. Then do the same during viewState updates. 
    const coords = new GeoCoordinates(viewState.latitude, viewState.longitude);
    this.mapView.geoCenter = coords;    
    const dist = MapViewUtils.calculateDistanceFromZoomLevel({focalLength: this.mapView.focalLength}, viewState.zoom+1);
    this.mapView.lookAt(coords, dist, viewState.pitch, viewState.bearing);
    this.mapView.zoomLevel = viewState.zoom+1;
}

onViewStateChange = ( { viewState } ) => {
    const coords = new GeoCoordinates(viewState.latitude, viewState.longitude);
    const dist = MapViewUtils.calculateDistanceFromZoomLevel({focalLength: this.mapView.focalLength}, viewState.zoom+1);
    this.mapView.lookAt(coords, dist, viewState.pitch, viewState.bearing);
    this.mapView.zoomLevel = viewState.zoom+1;
    this.setState( { viewState } );
}

This is how it looks on my end. I compared it with the static map and the arc is right on point where it should be.

unknown

Pessimistress commented 4 years ago

@gallickgunner Thank you for the code sample. I'm adding a get-started example for harp.gl integration based on your implementation: #4534