Create dicts that map styling to GeoJson features. :meta private:
| 875 | |
| 876 | |
| 877 | class GeoJsonStyleMapper: |
| 878 | """Create dicts that map styling to GeoJson features. |
| 879 | |
| 880 | :meta private: |
| 881 | """ |
| 882 | |
| 883 | def __init__( |
| 884 | self, |
| 885 | data: dict, |
| 886 | feature_identifier: str, |
| 887 | geojson_obj: GeoJson, |
| 888 | ): |
| 889 | self.data = data |
| 890 | self.feature_identifier = feature_identifier |
| 891 | self.geojson_obj = geojson_obj |
| 892 | |
| 893 | def get_style_map(self, style_function: Callable) -> TypeStyleMapping: |
| 894 | """Return a dict that maps style parameters to features.""" |
| 895 | return self._create_mapping(style_function, "style") |
| 896 | |
| 897 | def get_highlight_map(self, highlight_function: Callable) -> TypeStyleMapping: |
| 898 | """Return a dict that maps highlight parameters to features.""" |
| 899 | return self._create_mapping(highlight_function, "highlight") |
| 900 | |
| 901 | def _create_mapping(self, func: Callable, switch: str) -> TypeStyleMapping: |
| 902 | """Internal function to create the mapping.""" |
| 903 | mapping: TypeStyleMapping = {} |
| 904 | for feature in self.data["features"]: |
| 905 | content = func(feature) |
| 906 | if switch == "style": |
| 907 | for key, value in content.items(): |
| 908 | if isinstance(value, MacroElement): |
| 909 | # Make sure objects are rendered: |
| 910 | if value._parent is None: |
| 911 | value._parent = self.geojson_obj |
| 912 | value.render() |
| 913 | # Replace objects with their Javascript var names: |
| 914 | content[key] = "{{'" + value.get_name() + "'}}" |
| 915 | key = self._to_key(content) |
| 916 | feature_id = self.get_feature_id(feature) |
| 917 | mapping.setdefault(key, []).append(feature_id) # type: ignore |
| 918 | self._set_default_key(mapping) |
| 919 | return mapping |
| 920 | |
| 921 | def get_feature_id(self, feature: dict) -> Union[str, int]: |
| 922 | """Return a value identifying the feature.""" |
| 923 | fields = self.feature_identifier.split(".")[1:] |
| 924 | value = functools.reduce(operator.getitem, fields, feature) |
| 925 | assert isinstance(value, (str, int)) |
| 926 | return value |
| 927 | |
| 928 | @staticmethod |
| 929 | def _to_key(d: dict) -> str: |
| 930 | """Convert dict to str and enable Jinja2 template syntax.""" |
| 931 | as_str = json.dumps(d, sort_keys=True) |
| 932 | return as_str.replace('"{{', "{{").replace('}}"', "}}") |
| 933 | |
| 934 | @staticmethod |