apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
59.6k stars 19.58k forks source link

deformed geojson map #10253

Open mathiasleroy opened 5 years ago

mathiasleroy commented 5 years ago

Version

4.1.0-release

Steps to reproduce

get geojson map of belgium, then

echarts.registerMap('mymappp', geojson, {});

  series: [{
      name: '',
      type: 'map',
      coordinateSystem: 'geo',
      map: 'mymappp',
      roam: true, // allow zooming and translating
      zoom: zoom,
      itemStyle:{
        areaColor : 'white', // default area color, when no data
        emphasis:{label:{show:true}}
      },
      data:mapData,
        label: {
            normal: {
                show: false
            },
            emphasis: {
                show: false
            }
        }
  }],

What is expected?

normal shape of belgium

image

FYI: Lamberts the preferred projection for this country, here it means I used that coordinate system to encode the map.

What is actually happening?

deformed belgium map


cf. https://github.com/apache/incubator-echarts/issues/10252

echarts-bot[bot] commented 5 years ago

Hi! We've received your issue and please be patient to get responded. 🎉 The average response time is expected to be within one day for weekdays.

In the meanwhile, please make sure that you have posted enough image to demo your request. You may also check out the API and chart option to get the answer.

Have a nice day! 🍵

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it did not have recent activity. It will be closed in 7 days if no further activity occurs. If you wish not to mark it as stale, please leave a comment in this issue.

mathiasleroy commented 2 years ago

Not stale. Still waiting for solution.

mephinet commented 2 years ago

Hmmm, after reading the documentation and through a few relevant pieces of the code, I wonder how maps are supposed to work at all: There is no projection specified in the documentation or code, and there is no code that would be able to convert any given projection to one used by echarts. So my guess is this: Echarts currently is completely projection-naive (with the exception of the BMaps extension), and just plots the coordinate X/Y numbers without any awareness that they are projected/geodetic/geocentric/... That's why they are (and have to be) deformed... Maybe @pissang can enlighten me if I am missing something important here.

mephinet commented 2 years ago

This line looks suspicious to me: https://github.com/apache/echarts/blob/master/src/coord/geo/Geo.ts#L38 It sets the default aspectScale for GeoJSONs to 0.75 - where does this magic value come from? If I change it (in the debugger) to some other value, e.g. 2, then the map is deformed differently - so it seems to have an impact...

mephinet commented 2 years ago

I checked what Python's geopandas is doing, and copied their algorithm cf https://github.com/geopandas/geopandas/blob/v0.10.2/geopandas/plotting.py#L390 - and now my map is perfectly shaped.

  1. you need the bounding box of the GeoJSON. If it's not contained in the file, you'll need to calculate it manually
  2. calculate the correct aspectScale using this algorithm:
    const y_coord   = (bounds[1] + bounds[3]) / 2;
    const aspect    = Math.cos(y_coord * Math.PI / 180);
  3. add this property to your series:
    {type: "map", aspectScale: aspect, ...}

@mathiasleroy Maybe you can validate my solution? If so, I could try to make a pull request out of it...

leandrosoares6 commented 1 year ago

I checked what Python's geopandas is doing, and copied their algorithm cf https://github.com/geopandas/geopandas/blob/v0.10.2/geopandas/plotting.py#L390 - and now my map is perfectly shaped.

  1. you need the bounding box of the GeoJSON. If it's not contained in the file, you'll need to calculate it manually
  2. calculate the correct aspectScale using this algorithm:
  const y_coord   = (bounds[1] + bounds[3]) / 2;
  const aspect    = Math.cos(y_coord * Math.PI / 180);
  1. add this property to your series:
{type: "map", aspectScale: aspect, ...}

@mathiasleroy Maybe you can validate my solution? If so, I could try to make a pull request out of it...

Thanks!! Solved for me adding aspectScale in series!

mephinet commented 2 months ago

Having played around with more maps that extend to a large area of the earth, I learned that not using a projection is only a viable solution for countries that are either small or near the equator. The clean solution however is to always apply a projection. For this to become obvious, the examples would need to be extended to use a projection...

mathiasleroy commented 2 months ago

I think adding projections is what we need.
Since that is covered in #16364 I propose to close the current issue if no objections.