[使用i18n更改语言时,使用react-leaflet更新GeoJson上的工具提示

问题描述 投票:0回答:1

由于react-leaflet,我目前正在显示带有GeoJSON组件的Map。我还在悬停在某些国家/地区上显示一些工具提示(例如,当我将鼠标悬停在法国时,工具提示显示为“法国”)。我也正在使用i18n进行国际化。问题是,当我切换语言时,它适用于整个页面,但不适用于这些工具提示。

我认为问题出在onEachFeature函数上,该函数在创建JSX Element GeoJSON时仅被调用一次,因此在切换语言时它不会更新。我认为是这样,因为工具提示在显示时是正确的语言(如果最初将语言设置为法语,则工具提示将使用法语,如果将语言设置为英语,则将它们设置为英语)。但是,当我们在GeoJSON组件初始化后更改语言时,它们根本不会更新。

我希望我已经说清楚了>

这是我的界面:

interface position {
  latlng: LatLngLiteral,
  tooltip: string
}

interface state {
  markers: position[],
  zoom: number,
  display: position[] | any,
  geoJson: any,
  countries: { [key: string]: position }
}

这里是我组件的开头:

// t is the translation function, that should translate in the selected language. It is dynamic, it means that when we switch languages, it automatically update the translated string
const { t }: { t: TFunction } = useTranslation();

const countryToString = (countries: string[]): string => countries.join(", ");
  // List of position and label of tooltip for the GeoJson object, for each country
const countries: { [key: string]: position } = {
    DEU: {
      latlng: {
        lat: 51.0834196,
        lng: 10.4234469,
      },
      tooltip: countryToString([
        t("travel.germany.munich"),
        t("travel.germany.berlin"),
        t("travel.germany.hamburg"),
        t("travel.germany.munster"),
        t("travel.germany.country"),
      ])
    },
    CZE: {
      latlng: {
        lat: 49.667628,
        lng: 15.326962,
      },
      tooltip: countryToString([
        t("travel.tchequie.prague"),
        t("travel.tchequie.country"),
      ])
    },
...
}

// List of position and tooltip for the cities Markers
const cities: position[] = [
    {
      latlng: {
        lat: 48.13825988769531,
        lng: 11.584508895874023,
      },
      tooltip: t("travel.germany.munich"),
    },
    {
      latlng: {
        lat: 52.51763153076172,
        lng: 13.40965747833252,
      },
      tooltip: t("travel.germany.berlin"),
    },
...

[我有一个国家列表,这要归功于GeoJSON组件,我要显示一个城市列表,而这要归功于我通过Marker列表来显示的。

然后是功能部分:


  // Contains the json containing the polygons of the countries
  const data: geojson.FeatureCollection = geoJsonData as geojson.FeatureCollection;
  let geoJson: any = <GeoJSON
    key='my-geojson'
    data={data}
    style={() => ({
      color: '#4a83ec',
      weight: 1,
      fillColor: "#1a1d62",
      fillOpacity: 0.25,
    })}

    // PROBLEM : does not update the tooltips when we switch languages
    // FIX ME
    onEachFeature={(feature: geojson.Feature<geojson.GeometryObject>, layer: Layer) => {
      layer.on({
        'mouseover': (e: LeafletMouseEvent) => {
          const country = state.countries[e.target.feature.properties.adm0_a3];
          layer.bindTooltip(country.tooltip);
          layer.openTooltip(country.latlng);
        },
        'mouseout': () => {
          layer.unbindTooltip();
          layer.closeTooltip();
        },
      });
    }}
  />


  const [state, setState] = useState<state>({
    markers: cities,
    zoom: 3,
    geoJson: geoJson,
    display: geoJson,
    countries: countries
  });

  // Update on zoom change
  function onZoom(e: LeafletMouseEvent): void {
    const zoom = e.target._zoom;
    const newDisplay = updateDisplay(zoom);
    setState({
      ...state,
      zoom,
      display: newDisplay,
    });
  }

  // Called on every zoom change, in order to display either the GeoJson, or the cities Marker
  function updateDisplay(zoom: number): Marker[] | any {
    if (zoom >= 4) {
      return (state.markers.map(
        (
          c: position,
          i: number
        ) => {
          return (
            <Marker key={c.latlng.lat + c.latlng.lng} position={c.latlng}>
              <Tooltip>{c.tooltip}</Tooltip>
            </Marker>
          );
        }
      ));
    } else {
      return state.geoJson;
    }
  }

  return (
    <Map
      style={{ height: "500px" }}
      center={[54.370138916189596, -29.918133437500003]}
      zoom={state.zoom}
      onZoomend={onZoom}
    >
      <TileLayer url="https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw" />
      {state.display}
    </Map>
  );

[如果您想查看整个代码,则可以在此处看到:https://github.com/TheTisiboth/WebCV/blob/WIP/src/components/customMap.tsx

由于react-leaflet,我目前正在显示带有GeoJSON组件的Map。我还在悬停在某些国家/地区上显示一些工具提示(例如,当我将鼠标悬停在法国时,工具提示显示为“ ...

reactjs leaflet tooltip geojson i18next
1个回答
0
投票

显然,该插件无法处理以"travel.italy.roma, travel.italy.naples, travel.italy.pompei, travel.italy.country形式连接的多个连接字符串,而且更重要的是,您似乎需要将函数调用放置在标记中(不是100%确定为什么原因,我不熟悉此插件-也许还有其他选择。

 <Map
  style={{ height: "500px" }}
  center={[54.370138916189596, -29.918133437500003]}
  zoom={state.zoom}
  onZoomend={onZoom}
>
  <TileLayer url='https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw' />
  {state.markers.map(
    (c: position, i: number): ReactElement => {
      if (state.zoom >= 5) {
        return (
          <Marker key={i} position={[c.lat, c.lon]}>
            <Tooltip>{t(c.tooltip)}</Tooltip>
          </Marker>
        );
      } else {
        return (
          <CircleMarker
            key={i}
            center={[c.lat, c.lon]}
            color='red'
            radius={state.radius}
          >
            <Tooltip>{t(c.tooltip)}</Tooltip>
          </CircleMarker>
        );
      }
    }
  )}
</Map>
© www.soinside.com 2019 - 2024. All rights reserved.