GithubHelp home page GithubHelp logo

Comments (2)

wibed avatar wibed commented on May 26, 2024

to put it into perspective. ive had a look at the source code from the old geocoder
and it resulted in this:

a full example would be appreciated

  const getMapboxMap = () => {
    const { mapRef } = props
    return (mapRef && mapRef.current && mapRef.current.getMap()) || null
  }

  const getContainerNode = () => {
    const { containerRef } = props
    return (containerRef && containerRef.current) || null
  }
  
  
  const geocoder = useControl<MapboxGeocoder>(
    () => {

      const ctrl = new MapboxGeocoder({
        ...props,
        marker: false,
        accessToken: props.mapboxAccessToken,
        reverseGeocode: false
      });

      ctrl.on('clear', event => {
        onClear(event)
        setMarker(null)
      });

      ctrl.on('error', onError);

      ctrl.on('loading', event => {

        onLoading(event)


      });

      ctrl.on('results', onResults);

      ctrl.on('result', event => {

        onResult(event);

        const { result } = event;


        const location = result && (
          result.center || (result.geometry?.type === 'Point' && result.geometry.coordinates)
        );

        if (location) { setMarker(<Marker longitude={location[0]} latitude={location[1]} />) }
        else { setMarker(null) }
      });

      ctrl.on('error', onError);

      const mapboxMap = getMapboxMap()
      const containerNode = getContainerNode()

      if (mapboxMap && containerNode) {
        console.log("append")
        containerNode.appendChild(ctrl.onAdd(mapboxMap))
      }

      return ctrl;
    },
    {}
  );

from react-map-gl.

wibed avatar wibed commented on May 26, 2024

i ended up with a working example. the culprit was me passing refs wrong.

here is my version, feel free to use it in any way you like.

import React, { forwardRef, useRef, useState, PropsWithChildren } from 'react';

import mapboxgl from 'mapbox-gl';
import ReactMapGL, { useControl, Marker } from 'react-map-gl';
import MapboxGeocoder, { GeocoderOptions } from '@mapbox/mapbox-gl-geocoder';


type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
  mapboxAccessToken: string;
  onMarker?: any; //boolean | Omit<MarkerProps, 'longitude' | 'latitude'>;

  position?: any; //ControlPosition;

  onClear?: (e: object) => void;
  onLoading?: (e: object) => void;
  onResults?: (e: object) => void;
  onResult?: (e: object) => void;
  onError?: (e: object) => void;
}

export const GeocoderControl = forwardRef(({
  ...props
}: GeocoderControlProps, ref: any) => {

  const { mapRef, containerRef } = ref

  const [marker, setMarker] = useState<any>(null);

  const {
    onClear = () => true,
    onResult = () => true,
    onError = () => true,
    onResults = () => true,
    onLoading = () => true
  } = props

  const getMapboxMap = () => {
    return (mapRef && mapRef.current && mapRef.current.getMap()) || null
  }

  const getContainerNode = () => {
    return (containerRef && containerRef.current) || null
  }

  const geocoder = useControl<MapboxGeocoder>(
    () => {

      const mapboxMap = getMapboxMap()
      const containerNode = getContainerNode()

      const ctrl = new MapboxGeocoder({
        ...props,
        marker: false,
        accessToken: props.mapboxAccessToken,
        reverseGeocode: false
      });

      if (mapboxMap && containerNode && !containerNode.hasChildNodes()) {
        containerNode.appendChild(ctrl.onAdd(mapboxMap))
      }

      ctrl.on('clear', event => {
        onClear(event)
        setMarker(null)
      });

      ctrl.on('error', onError);

      ctrl.on('loading', event => {
        onLoading(event)
      });

      ctrl.on('results', event => {
        onResults(event)
      });

      ctrl.on('result', event => {

        onResult(event);

        const { result } = event;

        const location = result && (
          result.center || (result.geometry?.type === 'Point' && result.geometry.coordinates)
        );

        if (location) { setMarker(<Marker longitude={location[0]} latitude={location[1]} />) }
        else { setMarker(null) }
      });

      ctrl.on('error', onError);

      return ctrl;
    }, {}
  );


  // @ts-ignore (TS2339) private member
  if (geocoder._map) {
    if (geocoder.getProximity() !== props.proximity && props.proximity !== undefined) {
      geocoder.setProximity(props.proximity);
    }
    if (geocoder.getRenderFunction() !== props.render && props.render !== undefined) {
      geocoder.setRenderFunction(props.render);
    }
    if (geocoder.getLanguage() !== props.language && props.language !== undefined) {
      geocoder.setLanguage(props.language);
    }
    if (geocoder.getZoom() !== props.zoom && props.zoom !== undefined) {
      geocoder.setZoom(props.zoom);
    }
    if (geocoder.getFlyTo() !== props.flyTo && props.flyTo !== undefined) {
      geocoder.setFlyTo(props.flyTo);
    }
    if (geocoder.getPlaceholder() !== props.placeholder && props.placeholder !== undefined) {
      geocoder.setPlaceholder(props.placeholder);
    }
    if (geocoder.getCountries() !== props.countries && props.countries !== undefined) {
      geocoder.setCountries(props.countries);
    }
    if (geocoder.getTypes() !== props.types && props.types !== undefined) {
      geocoder.setTypes(props.types);
    }
    if (geocoder.getMinLength() !== props.minLength && props.minLength !== undefined) {
      geocoder.setMinLength(props.minLength);
    }
    if (geocoder.getLimit() !== props.limit && props.limit !== undefined) {
      geocoder.setLimit(props.limit);
    }
    if (geocoder.getFilter() !== props.filter && props.filter !== undefined) {
      geocoder.setFilter(props.filter);
    }
    if (geocoder.getOrigin() !== props.origin && props.origin !== undefined) {
      geocoder.setOrigin(props.origin);
    }
    // Types missing from @types/mapbox__mapbox-gl-geocoder
    // if (geocoder.getAutocomplete() !== props.autocomplete && props.autocomplete !== undefined) {
    //   geocoder.setAutocomplete(props.autocomplete);
    // }
    // if (geocoder.getFuzzyMatch() !== props.fuzzyMatch && props.fuzzyMatch !== undefined) {
    //   geocoder.setFuzzyMatch(props.fuzzyMatch);
    // }
    // if (geocoder.getRouting() !== props.routing && props.routing !== undefined) {
    //   geocoder.setRouting(props.routing);
    // }
    // if (geocoder.getWorldview() !== props.worldview && props.worldview !== undefined) {
    //   geocoder.setWorldview(props.worldview);
    // }
  }

  return marker
})


// type FloorMapProps = Pick<PropsWithChildren> & {
//   initial: any;
//   onMove: any;
//   onResult: any;
//   onClear: any;
//   setSelection: any;
//   searchResult: any;
// }

export const FloorMap = forwardRef(({
  initial,
  onMove,
  onResult,
  onClear,
  setSelection,
  searchResult,
  // containerRef,
  viewportRef,
  ...props
}: any, ref: any) => {

  const { mapRef } = ref

  const settingPadding = 2
  const element = viewportRef
  const parent = element.parentNode
  const paddingTop = element.offsetTop
  const paddingLeft = element.offsetLeft
  const paddingRight = parent.offsetWidth - paddingLeft - element.offsetWidth - settingPadding
  const paddingBottom = parent.offsetHeight - paddingTop - element.offsetHeight - settingPadding

  // const { MAPBOX_PUBLIC_TOKEN, MAPBOX_STYLE_URL } = process.env


  if (!MAPBOX_PUBLIC_TOKEN) throw new Error("No public token for the maxbox api implemented")
  if (!MAPBOX_STYLE_URL) throw new Error("No style url for the mapbox api implemented")

  const [isSearch, setIsSearch] = useState<boolean | undefined>(false)

  const _onResult = (e) => {
    onResult(e)
    setIsSearch(undefined)
  }

  const _onClear = (e) => {
    onClear(e)
    setIsSearch(false)
  }

  return (
    <ReactMapGL
      ref={mapRef}
      onMove={(e) => onMove(e)}
      onLoad={(e) => {
        if (mapRef.current !== null) {
          const obj: any = mapRef.current
          if (obj.resize) {
            obj.easeTo({
              padding: {
                left: paddingLeft,
                top: paddingTop,
                right: paddingRight,
                bottom: paddingBottom
              }
            })

            obj.resize()
          }
        }
      }}
      mapStyle={`${MAPBOX_STYLE_URL}`}
      mapboxAccessToken={`${MAPBOX_PUBLIC_TOKEN}`}
      {...initial}
      width={'100%'}
      height={'100%'}
    >
      <style>{`
        .mapboxgl-map {
          position: absolute !important;
          top: 0;
          bottom: 0;
          width: 100% !important;
          height: 100% !important;
        }
        .mapboxgl-canvas {
          left: 0;
        }
        .mapboxgl-ctrl-logo, 
        .mapboxgl-ctrl-attrib, 
        .mapboxgl-ctrl-geocoder--powered-by {
          display: none !important;
        }
      `}</style>
      {mapRef && mapRef.current !== undefined
        &&

        < GeocoderControl
          ref={ref}
          mapboxAccessToken={MAPBOX_PUBLIC_TOKEN}
        />
      }

      {searchResult.map((el, idx) => (
        <div key={el.lon}>
          <Marker
            longitude={el.lon}
            latitude={el.lat}
          >
            <p
              className="h-6 w-6 cursor-pointer fill-white"
              onClick={() => setSelection(
                (prev) => prev === idx
                  ? undefined
                  : idx
              )}
            >
              <div>H</div>
            </p>
          </Marker>
        </div>
      ))}
    </ReactMapGL>
  )
})

from react-map-gl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.