使用React-Map-Gl(MAPBOX)显示具有自定义属性的HTML群集

发布于 2025-02-02 21:56:18 字数 4482 浏览 4 评论 0原文

我正在尝试调整示例 带有自定义的显示html clusters属性 对于react-map-gl

我没有基本的群集,没有自定义样式工作(改编自群集 ):

<ReactMapGL ref={mapRef}>
    <Source id="poi-modal-geojson" type="geojson" data={pointsToGeoJSONFeatureCollection(points)}
        cluster={true}
        clusterMaxZoom={14}
        clusterRadius={50}
    >
        <Layer {...{
                id: 'clusters',
                type: 'circle',
                source: 'poi-modal-geojson',
                filter: ['has', 'point_count'],
                paint: {
                    'circle-color': [
                        'step',
                        ['get', 'point_count'],
                        '#51bbd6',
                        100,
                        '#f1f075',
                        750,
                        '#f28cb1'
                    ],
                    'circle-radius': [
                        'step',
                        ['get', 'point_count'],
                        20,
                        100,
                        30,
                        750,
                        40
                    ]
                }
        }} />
        <Layer {...{
            id: 'unclustered-point',
            type: 'circle',
            source: 'poi-modal-geojson',
            filter: ['!', ['has', 'point_count']],
            paint: {
                'circle-color': '#11b4da',
                'circle-radius': 4,
                'circle-stroke-width': 1,
                'circle-stroke-color': '#fff'
            }
        }} />
    </Source>
</ReactMapGL>

在这里,pointStStoGeojSonFeatUrecollection(点:any []):Geojson.featUrecollection&lt; geojson.geojson.geometry&gt;是返回geojson的函数“ https://github.com/nitaliano/reeact-native-mapbox-gl/issues/1069#issuecomment-370192838” rel =“ nofollow noreferrer”>在这里)。

但是,我需要更复杂的标记样式,并且正在尝试适应 显示具有自定义属性的HTML群集 到目前为止没有成功。我主要尝试调整updateMarkers(),并在useeffect()中调用它:

const mapRef: React.Ref<MapRef> = React.createRef();
const markers: any = {};
let markersOnScreen: any = {};

useEffect(() => {
    const map = mapRef.current.getMap();

    function updateMarkers() {
        const newMarkers: any = {};
        const features = map.querySourceFeatures('poi-modal-geojson');

        // for every cluster on the screen, create an HTML marker for it (if we didn't yet),
        // and add it to the map if it's not there already
        for (const feature of features) {
            const coords = feature.geometry.coordinates;
            const props = feature.properties;
            if (!props.cluster) continue;
            const id = props.cluster_id;
            
            let marker = markers[id];
            if (!marker) {
                let markerProps = {
                    key: 'marker' + id,
                    longitude: coords[0],
                    latitude: coords[1],
                    className: 'mapboxgl-marker-start'
                }
                const el = React.createElement(Marker, markerProps, null),
                marker = markers[id] = el;
            }
            newMarkers[id] = marker;
            
            if (!markersOnScreen[id]) {
                // TODO re-add
                // marker.addTo(map);
            }
        }
        // for every marker we've added previously, remove those that are no longer visible
        for (const id in markersOnScreen) {
            if (!newMarkers[id]) delete markersOnScreen[id];
        }
        markersOnScreen = newMarkers;
    }

    // after the GeoJSON data is loaded, update markers on the screen on every frame
    map.on('render', () => {
        if (!map.isSourceLoaded('poi-modal-geojson')) return;
        updateMarkers();
    });
}, [points]);

不幸的是,使用标记使用react.createelement创建的标记 ()未显示我不确定在updatemarkers()中创建Marker元素的正确方法是什么,或者如果我的方法完全错误。

I am trying to adapt the example Display HTML clusters with custom properties for react-map-gl.

I got basic clusters without custom styling working (adapted from Create and style clusters):

<ReactMapGL ref={mapRef}>
    <Source id="poi-modal-geojson" type="geojson" data={pointsToGeoJSONFeatureCollection(points)}
        cluster={true}
        clusterMaxZoom={14}
        clusterRadius={50}
    >
        <Layer {...{
                id: 'clusters',
                type: 'circle',
                source: 'poi-modal-geojson',
                filter: ['has', 'point_count'],
                paint: {
                    'circle-color': [
                        'step',
                        ['get', 'point_count'],
                        '#51bbd6',
                        100,
                        '#f1f075',
                        750,
                        '#f28cb1'
                    ],
                    'circle-radius': [
                        'step',
                        ['get', 'point_count'],
                        20,
                        100,
                        30,
                        750,
                        40
                    ]
                }
        }} />
        <Layer {...{
            id: 'unclustered-point',
            type: 'circle',
            source: 'poi-modal-geojson',
            filter: ['!', ['has', 'point_count']],
            paint: {
                'circle-color': '#11b4da',
                'circle-radius': 4,
                'circle-stroke-width': 1,
                'circle-stroke-color': '#fff'
            }
        }} />
    </Source>
</ReactMapGL>

Here, pointsToGeoJSONFeatureCollection(points: any[]): GeoJSON.FeatureCollection<GeoJSON.Geometry> is a function returning a GeoJSON (adapted from here).

However, I need more complex styling of markers and I am trying to adapt Display HTML clusters with custom properties without success so far. I mainly tried to adapt updateMarkers() and to call it inside useEffect():

const mapRef: React.Ref<MapRef> = React.createRef();
const markers: any = {};
let markersOnScreen: any = {};

useEffect(() => {
    const map = mapRef.current.getMap();

    function updateMarkers() {
        const newMarkers: any = {};
        const features = map.querySourceFeatures('poi-modal-geojson');

        // for every cluster on the screen, create an HTML marker for it (if we didn't yet),
        // and add it to the map if it's not there already
        for (const feature of features) {
            const coords = feature.geometry.coordinates;
            const props = feature.properties;
            if (!props.cluster) continue;
            const id = props.cluster_id;
            
            let marker = markers[id];
            if (!marker) {
                let markerProps = {
                    key: 'marker' + id,
                    longitude: coords[0],
                    latitude: coords[1],
                    className: 'mapboxgl-marker-start'
                }
                const el = React.createElement(Marker, markerProps, null),
                marker = markers[id] = el;
            }
            newMarkers[id] = marker;
            
            if (!markersOnScreen[id]) {
                // TODO re-add
                // marker.addTo(map);
            }
        }
        // for every marker we've added previously, remove those that are no longer visible
        for (const id in markersOnScreen) {
            if (!newMarkers[id]) delete markersOnScreen[id];
        }
        markersOnScreen = newMarkers;
    }

    // after the GeoJSON data is loaded, update markers on the screen on every frame
    map.on('render', () => {
        if (!map.isSourceLoaded('poi-modal-geojson')) return;
        updateMarkers();
    });
}, [points]);

Unfortunately, the Marker created using React.createElement() isn't displayed I am not sure what is the right approach to create Marker elements in updateMarkers() or if my approach is completely wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ㄖ落Θ余辉 2025-02-09 21:56:18

有一篇关于标记集群的精彩文章,它使用了超级集群用use-supercluster 库,它使得群集不仅对于地图框,而且对于其他地图库也很容易您可以找到它在这里

您只需要将点转换为geojson特征对象即可将其传递到useupercluster钩子,并使计算工作。它将根据您当前的视口返回一系列积分和群集,您可以通过它映射并基于element.properties.cluster.cluster flag在相应地显示元素。

Geojson功能对象的属性属性可以是自定义的,因此您可以在获得最终群集数组时传递任何需要显示标记的内容。

There is a great article on marker clustering which uses the supercluster and use-supercluster libraries and it makes clustering really easy not only for map box but for other map libraries as well, you can find it here.

You just have to convert your points into GeoJSON Feature objects in order to pass them to the useSupercluster hook and for the calculations to work. It will return an array of points and clusters depending on your current viewport, and you can map through it and display the elements accordingly based on the element.properties.cluster flag.

The properties property of the GeoJSON Feature object can be custom so you can pass whatever you need to display the markers later on when you get the final cluster array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文