Skip to content

Add topojson support / EMS v3 support - #15361

Merged
thomasneirynck merged 24 commits into
elastic:masterfrom
thomasneirynck:enh/topojson
Jan 16, 2018
Merged

thomasneirynck merged 24 commits into
elastic:masterfrom
thomasneirynck:enh/topojson

Conversation

@thomasneirynck

@thomasneirynck thomasneirynck commented Dec 2, 2017 •

Copy link
Copy Markdown
Contributor

This PR adds support for Topojson and the EMS v3 maps backend. It also refactors some of the common code between Coordinate Map and Region Map.


This is a rough outline for adding topojson support to Region Maps. Closes #14331.

Adding topojson layers raises a few new issues that need to be solved.

  • I'm not sure the current single format as a string parameter will be sufficient. We need more metadata for topojson , which includes the path where the features are in the topology.
  • the current joining mechanism is too slow. We potentially need to join tens of thousands of geojson features against thousands of ES term-buckets. I changed it to use a map, but even that should be improved. It's probably wrong to rely on the onFeature callbacks coming out of Leaflet, which have no defined order. Rather, we should just do that join ourselves. (SHOULD EVALUATE IF THIS WAS WORTH IT)
  • the current outline styling is too thick. Since we'll have more features, they'll tend to be smaller, so we should make the outline configurable (cf. Make line styling of region maps configurable #15360)
  • we should offer the ability to exclude shapes from the map if they don't match any of the terms. Right now, they stay on as unstyled features. The annoying part is that to do with we have to recreate the leaflet layer from scratch because filtering cannot be applied after layer instantiation.
  • multi-baselayer support. This requires more changes to the manifest, so we can display something human readable.

@nyurik

nyurik commented Dec 2, 2017

Copy link
Copy Markdown
Contributor

In theory we could standardize our topojsons to always have the same object hierarchy. We don't have to use multiple top-level subobjects, but instead standardize on {objects:{data: ...}}. In this case we won't need to store extra topojson file-specific metadata.

@nyurik

nyurik commented Dec 2, 2017

Copy link
Copy Markdown
Contributor

P.S. I used this approach in Kartotherian - https://github.com/kartotherian/geoshapes/blob/master/geoshapes.js#L406

@thomasneirynck thomasneirynck changed the title [WIP] add topojson support [WIP] add topojson support / EMS v3 support Dec 12, 2017
@thomasneirynck

Copy link
Copy Markdown
Contributor Author

I'm going to expand this PR to support other EMS v3 features

  • include multi-baselayer support
  • add docs for custom configs for on-prem deployments

@thomasneirynck

thomasneirynck commented Dec 13, 2017 •

Copy link
Copy Markdown
Contributor Author

I added support for multibase layer (hypothetical, since EMS doesn't publish multiple layers yet). It's a rough outline, not intende to go in as-is. I changed the wms-options now to wrap the entire baselayer configuration.

For some reason, this broke the Coordinate Map visualization. It's broken even when excluding the wms-options Not sure why yet.. due to zoom-settings not being applied correctly. will fix.

@thomasneirynck

thomasneirynck commented Dec 13, 2017 •

Copy link
Copy Markdown
Contributor Author

@timroes @ppisljar This is an outline still, but most of the features that should go in, are in. I'm not sure if we need "more" features in order to support the use-case. Tests/docs are missing.

The biggest issue is that we actually don't have an EMS v3 yet. So this requires some manual configurations in the yaml to make topojson work.

Things that can be evaluated already:

  • do join upfront and don't rely on looping over features in Leaflet. This is a huge performance win when dealing with a lot of shapes. It does introduce more complexity though. For example, we need to rejoin each time the terms-data changes.
  • ability to only display matching shapes. This has an impact on our ability of reusing choroplethlayer-instances. You can't remove features from leaflet-layers or change filters-on-the-fly, so we might have to recreate the instance if the data changes.
  • multi-baselayer support (right now only showing single option, see EMSv3 comment above). I redid the existing wms-option directive and moved it there. This addition impacts the Coordinate Map as well, and required changes to the serviceSettings loader
  • new line-width configuration

I'd like to merge #15507 as well, so I can rebase with the added unit tests. So I'd prioritize that one first for review.

@thomasneirynck thomasneirynck changed the title [WIP] add topojson support / EMS v3 support Add topojson support / EMS v3 support Dec 15, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<tile-map-vis-params>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Get rid of the link function if we don't need it.
  • Use child scope for the directive instead of writing to vis.params directly in the template.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@timroes
timroes self-requested a review December 18, 2017 18:07
@nyurik

nyurik commented Dec 18, 2017

Copy link
Copy Markdown
Contributor

I wonder if we should integrate https://github.com/briannaAndCo/Leaflet.Antimeridian into this as well, to solve all potential anti-meridian issues. Might need to evaluate performance hit, or make it optional (e.g. the catalog file will mark a certain dataset as requiring a special antimeridian handling)

@thomasneirynck
thomasneirynck force-pushed the enh/topojson branch 2 times, most recently from 2747325 to d195a76 Compare December 29, 2017 19:56
@thomasneirynck

Copy link
Copy Markdown
Contributor Author

Attached is an example topojson file that you can use for testing. It works with the makelogs data.

world_countries.topojson.zip

Drop it in src/core_plugins/region_map/public/data and use following configuration in the kibana.yml:

regionmap:
  includeElasticMapsService: true
  layers:
     - name: "World countries (self hosted, topojson)"
       url: "../plugins/region_map/data/world_countries.topojson"
       format:
          type: 'topojson'
       meta:
          feature_collection_path: 'collection'
       fields:
          - name: "iso2"
            description: "Two letter abbreviation"

@ppisljar ppisljar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minor comments and some additional questions ...
need to do some more testing before approving

Comment thread package.json Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module doesn't seem to be much used and kept up to date ? (seems last change was half a year ago). Can we rely on it ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems legit to me. Written by the creator of d3 and frequently downloaded. It's a subset of https://www.npmjs.com/package/topojson, with only some conversion functions.

Comment thread src/core_plugins/kibana/inject_vars.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ups ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only change in this file is the removal of this empty line ....

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, oops! ;)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was the default outlineWeight before ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment should probably move on its own line to make it easier to notice.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are this defaults hardcoded here and not read from vis.params ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These settings are driven by the base-layers and those are read from the EMS-manifests. These are just placeholders when we create the map, but they get overridden as baselayers are configured.

I did create variables for them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only updating map zoom if maxZoom is bigger than current maxZoomLevel ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes to this file are unnecessary, should remove to make the change cleaner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you quickly explain why all this calls to updateChoroplethLayer ? (4 calls to updateChoroplethLayerForXXX)

@thomasneirynck thomasneirynck Jan 9, 2018 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking into this more in-depth, I can't really trigger this being called 4 times in a single render call.

This may get called 2 times in a single render call. Once when there is a data change and once when there is a change in the params.

These checks arose due to a limitation of leaflet, that doesn't allow us to change the data after we have assigned it to a layer. That's why we need to check if we can reuse the existing layer or create a new instance. Whether we can reuse it depends on a number of factors:

  • if any parameters change that affect the join-parameters, we cannot reuse the instance
  • if the data changes, we cannot reuse the instance.

I think it is working as intended. The checks avoid recreating an instance of the leaflet-layer and downloading new data when we shouldn't. This is an important feature. If we remove this and redraw the visualization from scratch for each render call, this will absolutely kill responsiveness of the map.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this diff got really bad, most of this functions did not really change just their position in the file did ....

@thomasneirynck

thomasneirynck commented Jan 9, 2018 •

Copy link
Copy Markdown
Contributor Author

@nyurik wrt. antemeridian. I wouldn't make this part of this PR, but we can consider it. Our reliance on leaflet plugins is a long term liability rather than an asset. I'd reevaluate when we get more community feedback on this issue. Feel free to create a bug report for it too.

@ppisljar

Copy link
Copy Markdown
Contributor

i don't have any more comments on code and as far as i could test this seems to work.
waiting for docs and tests to pass.

timroes
timroes previously approved these changes Jan 12, 2018

@timroes timroes left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides some minor code suggestions and the still missing tests and docs this LGTM. Though, also after some readings and watching Thomas' explanation to Peter, I still don't have a very deep understanding of the domain, so not sure if I could validate everything correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we shouldn't rely on non breaking whitespaces for styling, but rather fix the accordingly CSS. Also as far as I know since the switch to EUI, these icons now looks okay spacing wise. Maybe rebase this on master and remove that whitespace.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be removed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the true isn't needed here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I preferred the promise to resolve to a success-flag iso. of just undefined, as it's being used as a boolean check by the client.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with leaving it in, even though I think, the promise should just reject if there are cases where it's not successful, and a resolved promise should always mean successful, which would render the true useless imho. But I won't nitpick on this one :D

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree 100% that if promise was not succesful it should reject instead of resolve with false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be shortened, by using the .find method?

const fileService = catalogue.services.find(service => service.type === 'file');
if (!fileService) {
  return [];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.find could be used here too

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

jenkins, test this

@timroes

timroes commented Jan 16, 2018

Copy link
Copy Markdown
Contributor

Please don't comment out tests, but rather use .skip so it will still be tracked, that these tests exist, and just skipped for the moment. Please also open an issue for all skipped tests, to investigate and get them working again.

const northWest = bounds.getNorthWest();
if (
southEast.lng === northWest.lng &&
southEast.lng === northWest.lng ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the and-case didn't trap the case where the visualization would have a width, but not a height (or vice-versa).

@ppisljar

Copy link
Copy Markdown
Contributor

seems old map visualizations (saved before this PR) no longer work on dashboard:

screenshot-localhost-5601 2018-01-16 09-42-42-354

@timroes

timroes commented Jan 16, 2018 •

Copy link
Copy Markdown
Contributor

Does this PR break previously created visualizations, that has a custom map server configured? They would now require a EMSv3 server, while beforehand an EMSv2. Is EMSv3 backward compatible, so this visualization will still work with any EMSv2 server? If not I think we need a breaking change warning on this, since it would require all users with custom map servers to update Kibana in parallel to upgrade their map server to use EMSv3.

@ppisljar

Copy link
Copy Markdown
Contributor

old visualizations should still work, we can't expect users to recreate all their map visualizations.

same seems to happen for region map

@timroes
timroes dismissed their stale review January 16, 2018 09:12

Dismiss Approval until backward compatibility is fixed.

@thomasneirynck

thomasneirynck commented Jan 16, 2018 •

Copy link
Copy Markdown
Contributor Author

@timroes there doesn't need to be backward compatibility between Kibana 6.2 and up, and EMSv2. Kibana 6.2 will only connect to EMSv3 and never to any of the older EMS-endpoints. Likewise, none of the older versions of Kibana will connect to EMSv3.

From the EMS end, we do need to ensure that every service that is published in v2 remains available in EMSv3. This is to ensure that maps saved in older versions will have the same look&feel when reopened in a later version of Kibana.

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

thanks @ppisljar . That's a bug due to the service-settings for EMS only being loaded in the UI-editor component. I will fix this.

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

@timroes there are also no user-hosted EMS-versions, so users will not be able to run v2 themselves.

@ppisljar ppisljar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, i wonder if we could reenable the other test as well ?

expect(prettyPrint).to.equal('Today');
});
});
// describe('time changes', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about this test? could we reenable this one as well ?

@ppisljar

Copy link
Copy Markdown
Contributor

also update PR description and open a new issue for the docs and link it here ?

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

@ppisljar that test is flaky and fails/succeeds locally. it doesn't even have anything to do with maps, or even a populated dashboard. I created a separate ticket #16055, I'd prefer not get hung up on it for this PR.

+1 on separate doc ticket

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

last test run before merging.

jenkins, test this

@thomasneirynck
thomasneirynck merged commit 073f375 into elastic:master Jan 16, 2018
thomasneirynck added a commit to thomasneirynck/kibana that referenced this pull request Jan 16, 2018
This adds support for the v3 endpoint of the Elastic Maps Service. This includes support for Topojson files.
@thomasneirynck

thomasneirynck commented Jan 16, 2018 •

Copy link
Copy Markdown
Contributor Author

thomasneirynck added a commit that referenced this pull request Jan 16, 2018
This adds support for the v3 endpoint of the Elastic Maps Service. This includes support for Topojson files.
@thomasneirynck thomasneirynck added the Feature:Visualizations Generic visualization features (in case no more specific feature label is available) label Jan 23, 2018
@bhavyarm

bhavyarm commented Feb 6, 2018

Copy link
Copy Markdown
Contributor

@thomasneirynck do we have functional tests for this PR? Thanks!

@thomasneirynck

Copy link
Copy Markdown
Contributor Author

@bhavyarm there's no additional functional test, although there is more unit test.

This is mostly a backend change to accomodate the new EMS-service, less so a functional change in Kibana.

@aphelionz aphelionz mentioned this pull request Jun 12, 2018
34 of 48 tasks
patrykkopycinski pushed a commit to patrykkopycinski/kibana that referenced this pull request May 6, 2026
This adds support for the v3 endpoint of the Elastic Maps Service. This includes support for Topojson files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature:Region Map Feature:Visualizations Generic visualization features (in case no more specific feature label is available) release_note:enhancement v6.2.0 v7.0.0 WIP Work in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants