Skip to content

Commit

Permalink
Merge pull request #218 from emilhe/viewport
Browse files Browse the repository at this point in the history
Viewport
  • Loading branch information
emilhe committed Dec 27, 2023
2 parents 581ab6b + 01ea79b commit ac6804d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 12 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file.

## [1.0.13] - 27-12-23

### Changed

- Viewport tracking logic changed to use delta updates, which combined with a delay fixes [#211](https://github.com/emilhe/dash-leaflet/issues/211)
- Re-enable the ability to set `zoom`/`center` props (due to many user requests)

## [1.0.12] - 05-11-23

### Changed

- Bugfix in GeoJSON component correcting wrong behaviour when changing clustered data dynamically
- Correct GeoJSON data type definition (remove string as allowed type)

## [1.0.11] - 07-10-23

### Added
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "dash-leaflet",
"version": "1.0.11",
"version": "1.0.13",
"description": "Dash Leaflet is a light wrapper around React-Leaflet. The syntax is similar to other Dash components, with naming conventions following the React-Leaflet API.",
"main": "index.ts",
"repository": {
Expand Down
76 changes: 68 additions & 8 deletions src/ts/components/MapContainer.tsx
Expand Up @@ -4,13 +4,37 @@ import {resolveCRS, resolveEventHandlers, resolveRenderer} from '../utils';
// Force loading of basic leaflet CSS.
import '../../../node_modules/leaflet/dist/leaflet.css';
import {ClickEvents, KeyboardEvents, LoadEvents, MapContainerProps, DashComponent, Modify} from "../props";
import L from "leaflet";

const isEmpty = (obj) => {
return Object.keys(obj).length === 0;
}

const deltaZoomCenter = (map, zoom, center) => {
const centerObj = L.latLng(center);
const mapZoom = map.getZoom()
const mapCenter = map.getCenter()
// Check if anything changed.
const delta = {}
if(zoom != mapZoom){
delta['zoom'] = mapZoom
}
if(!centerObj.equals(mapCenter)) {
delta['center'] = mapCenter
}
return delta
}

const trackViewport = (map, props) => {
const delta = deltaZoomCenter(map, props.zoom, props.center);
// If the view didn't change, don't update anything.
if(isEmpty(delta)){
return
}
// Otherwise, issue the update.
const bounds = map.getBounds()
props.setProps({
zoom: map.getZoom(), center: map.getCenter(),
bounds: [[bounds.getSouth(), bounds.getWest()], [bounds.getNorth(), bounds.getEast()]]
})
delta['bounds'] = [[bounds.getSouth(), bounds.getWest()], [bounds.getNorth(), bounds.getEast()]]
props.setProps(delta)
}

function EventSubscriber(props) {
Expand All @@ -22,7 +46,8 @@ function EventSubscriber(props) {
}));
if(props.trackViewport) {
map.whenReady(() => {
trackViewport(map, props);
// The setTimeout ensures map is rendered before initial viewport tracking call.
setTimeout(()=>{trackViewport(map, props)}, 0);
})
}

Expand All @@ -36,9 +61,17 @@ function EventSubscriber(props) {
if(props.viewport === undefined){
return;
}
let {transition, center, zoom, options, bounds} = props.viewport;
// TODO: Should bounds take precedence?
let {transition, options, bounds, center, zoom} = props.viewport;
// If bounds are specified, they take precedence.
if(bounds){
bounds = new L.LatLngBounds(bounds)
// Check if update is needed.
if(map.getBounds().equals(bounds)){
console.log("BREAK BOUNDS CHANGE")
return;
}
// Issue the update.
console.log("ISSUE BOUNDS UPDATE")
switch (transition) {
case 'flyToBounds':
map.flyToBounds(bounds, options)
Expand All @@ -51,13 +84,20 @@ function EventSubscriber(props) {
}
return;
}
// Otherwise, read center/zoom if missing.
if(!center){
center = map.getCenter();
}
if(!zoom){
zoom = map.getZoom();
}
// TODO: Maybe check for change before invoking transition?
const delta = deltaZoomCenter(map, zoom, center)
// Check if an update is missing.
if(isEmpty(delta)){
console.log("BREAK CENTER/ZOOM CHANGE")
}
// Issue the update.
console.log("ISSUE CENTER/ZOOM CHANGE")
switch (transition) {
case 'flyTo':
map.flyTo(center, zoom, options)
Expand All @@ -70,6 +110,26 @@ function EventSubscriber(props) {
}
}, [props.viewport])

useEffect(function updateZoom(){
if(props.zoom === undefined){
return;
}
if(props.zoom == map.getZoom()){
return;
}
map.setZoom(props.zoom);
}, [props.zoom])

useEffect(function updateCenter(){
if(props.center === undefined){
return;
}
if(L.latLng(props.center).equals(map.getCenter())){
return;
}
map.setView(props.center);
}, [props.center])

return null
}

Expand Down
3 changes: 2 additions & 1 deletion src/ts/react-leaflet/GeoJSON.ts
Expand Up @@ -82,7 +82,7 @@ export type GeoJSONProps = Modify<Modify<FeatureGroupProps, GeoJSONOptions>, {
/**
* Data (consider using url for better performance). One of data/url must be set. [MUTABLE, DL]
*/
data?: string | object;
data?: object;

/**
* Url to data (use instead of data for better performance). One of data/url must be set. [MUTABLE, DL]
Expand Down Expand Up @@ -367,6 +367,7 @@ function _redraw(instance, props, map, geojson, index, toSpiderfyRef) {
map.fitBounds(dummy.getBounds())
}
// Draw the cluster.
instance.clearLayers();
_redrawClusters(instance, props, map, index, toSpiderfyRef)
}

Expand Down

0 comments on commit ac6804d

Please sign in to comment.