From 19df83936ddaa23205a7bacba6a34b07c3c8cf67 Mon Sep 17 00:00:00 2001 From: Ivan Kupriyanov Date: Mon, 26 Jul 2021 20:57:17 +0300 Subject: [PATCH] WIP: pass geocoder data (id and bbox) from Python to Kotlin --- .../jetbrains/livemap/plotDemo/LiveMap.kt | 97 ++++++++++++++++++- python-package/lets_plot/plot/geom.py | 25 ++--- python-package/lets_plot/plot/util.py | 13 --- 3 files changed, 102 insertions(+), 33 deletions(-) diff --git a/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt b/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt index 60c8cc06c91..0532312f7cb 100644 --- a/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt +++ b/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt @@ -11,9 +11,10 @@ import kotlin.random.Random class LiveMap { fun plotSpecList(): List> { return listOf( - blankPoint(), - blankMap(), - barWithNanValuesInData(), + georeference(), +// blankPoint(), +// blankMap(), +// barWithNanValuesInData(), //pieWithNullValuesInData(), //barWithNullValuesInData() // multiLayerTooltips() @@ -24,11 +25,97 @@ class LiveMap { // geom_point() // fourPointsTwoLayers(), // basic(), - bunch(), - facet() +// bunch(), +// facet() ) } + private fun georeference() : MutableMap { + val spec = """{ + "data": null, + "mapping": { + "x": null, + "y": null + }, + "data_meta": {}, + "ggsize": { + "width": 900, + "height": 400 + }, + "theme": { + "legend_position": "none" + }, + "kind": "plot", + "scales": [], + "layers": [ + { + "geom": "livemap", + "stat": null, + "data": null, + "mapping": { + "x": null, + "y": null + }, + "position": null, + "show_legend": null, + "sampling": null, + "tooltips": null, + "data_meta": {}, + "map": null, + "map_join": null, + "display_mode": null, + "location": null, + "zoom": null, + "projection": null, + "geodesic": null, + "tiles": { + "kind": "vector_lets_plot", + "url": "wss://tiles.datalore.jetbrains.com", + "theme": "color", + "attribution": "Map: \u00a9 Lets-Plot, map data: \u00a9 OpenStreetMap contributors." + }, + "geocoding": { + "url": "http://10.0.0.127:3020" + } + }, + { + "geom": "map", + "stat": null, + "data": null, + "mapping": { + "x": null, + "y": null + }, + "position": null, + "show_legend": null, + "sampling": null, + "tooltips": null, + "data_meta": {}, + "map": { + "id": [ + "148838", + "1428125" + ], + "country": [ + "usa", + "canada" + ], + "found name": [ + "United States", + "Canada" + ] + }, + "map_join": null, + "map_data_meta": { + "georeference": {} + } + } + ] +}""" + + return parsePlotSpec(spec) + } + private fun blankPoint(): MutableMap { val spec = """{ diff --git a/python-package/lets_plot/plot/geom.py b/python-package/lets_plot/plot/geom.py index a9c24420132..997f0517800 100644 --- a/python-package/lets_plot/plot/geom.py +++ b/python-package/lets_plot/plot/geom.py @@ -2,10 +2,10 @@ # Copyright (c) 2019. JetBrains s.r.o. # Use of this source code is governed by the MIT license that can be found in the LICENSE file. # +from lets_plot.geo_data_internals.utils import is_geocoder from .core import FeatureSpec, LayerSpec -from .util import as_annotated_data, as_annotated_map_data, is_geo_data_frame, auto_join_geo_names, \ +from .util import as_annotated_data, is_geo_data_frame, auto_join_geo_names, \ geo_data_frame_to_wgs84, normalize_map_join, get_geo_data_frame_meta -from lets_plot.geo_data_internals.utils import is_geocoder # # Geoms, short for geometric objects, describe the type of plot ggplot will produce. @@ -4238,18 +4238,16 @@ def process_map_parameters(): map_join = normalize_map_join(map_join) if is_geocoder(map): - if name in ['point', 'text', 'livemap']: - map = map.get_centroids() - elif name in ['map', 'polygon']: - map = map.get_boundaries() - elif name in ['rect']: - map = map.get_limits() - else: - raise ValueError("Geocoding doesn't provide geometries for geom_{}".format(name)) - - if is_geo_data_frame(map): + map = map.get_geocodes() + kwargs['map_data_meta'] = {'georeference': {} } + elif is_geo_data_frame(map): map_join = auto_join_geo_names(map_join, map) map = geo_data_frame_to_wgs84(map) + kwargs['map_data_meta'] = get_geo_data_frame_meta(map) + elif map is None: + pass + else: + raise ValueError('Invalid map parameter type: ' + repr(type(map))) if map_join is not None: kwargs['map_join'] = map_join @@ -4259,8 +4257,6 @@ def process_map_parameters(): process_map_parameters() - map_data_meta = as_annotated_map_data(kwargs.get('map', None)) - # TODO: check why map shouldn't be a GeoDataFrame if is_geo_data_frame(data) and not is_geo_data_frame(kwargs.get('map', None)): data = geo_data_frame_to_wgs84(data) @@ -4275,5 +4271,4 @@ def process_map_parameters(): sampling=sampling, tooltips=tooltips, **data_meta, - **map_data_meta, **kwargs) diff --git a/python-package/lets_plot/plot/util.py b/python-package/lets_plot/plot/util.py index a064dfb7f06..a2610011479 100644 --- a/python-package/lets_plot/plot/util.py +++ b/python-package/lets_plot/plot/util.py @@ -63,19 +63,6 @@ def is_data_pub_stream(data: Any) -> bool: return False -def as_annotated_map_data(raw_map: Any) -> dict: - if raw_map is None: - return {} - - if is_geocoder(raw_map): - return {'map_data_meta': {'georeference': {}}} - - if is_geo_data_frame(raw_map): - return {'map_data_meta': get_geo_data_frame_meta(raw_map)} - - raise ValueError('Unsupported map parameter type: ' + str(type(raw_map)) + '. Should be a GeoDataFrame.') - - def normalize_map_join(map_join): if map_join is None: return None