Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add style for geoJSON spec #44

Merged
merged 1 commit into from
Nov 23, 2021
Merged

Add style for geoJSON spec #44

merged 1 commit into from
Nov 23, 2021

Conversation

nboisteault
Copy link
Contributor

@nboisteault nboisteault commented Nov 19, 2021

Hi @jahow,
I have tried to make this PR work but the style stay as default when printing.
I don't understand why, do you have any hint?

@jahow
Copy link
Member

jahow commented Nov 22, 2021

Ok so this change is actually a bit more involved: as the style is generated asynchronously, the createLayerGeoJSON function has to be asynchronous as well (which was not the case before). This also means that the progress$ observable needs to first emit an initial value of [0, null] (indicating that the layer generation started) and then [1, context.canvas] after the style was obtained and the layer drawn.

Untested code but it may look like this:

function createLayerGeoJSON(layerSpec, rootFrameState) {
  const width = rootFrameState.size[0];
  const height = rootFrameState.size[1];
  const context = createCanvasContext2D(width, height);
  // @ts-ignore
  context.canvas.style = {};

  const vectorSource = new VectorSource({
    features: new GeoJSON().readFeatures(layerSpec.geojson),
  });

  const layer = new VectorLayer({
    source: vectorSource,
  });

  let frameState = makeLayerFrameState(rootFrameState, layer);
  let renderer = layer.getRenderer();
  // @ts-ignore
  renderer.useContainer = useContainer.bind(renderer, context);

  // use a behaviour subject for the progress observable
  const progress$ = new BehaviorSubject([0, null]);

  // when this promise resolves, the layer is ready to be drawn
  const styleReadyPromise = layerSpec.style ? 
    new OpenLayersParser()
      .writeStyle(layerSpec.style)
      .then((olStyle) => layer.setStyle(olStyle))
      .catch((error) => console.log(error))
    : Promise.resolve();

  // when ready, draw layer & send a complete progress value
  styleReadyPromise.then(() => {
    renderer.prepareFrame({ ...frameState, time: Date.now() });
    renderer.renderFrame({ ...frameState, time: Date.now() }, context.canvas);
    progress$.next([1, context.canvas]);
    progress$.complete();
  });

  return progress$;
}

Even if this doesn't work as is, I hope it will make it clearer what I meant about making the function asynchronous. Thanks!

@nboisteault
Copy link
Contributor Author

Perfect it works! Does this example is ok for the demo?

inkmap (30)

@jahow
Copy link
Member

jahow commented Nov 23, 2021

Looking good! Could you please also include a style in the rendering test for geojson layers?

@nboisteault
Copy link
Contributor Author

@jahow ready to merge! Thanks for your help.

@jahow jahow merged commit eb37e6f into camptocamp:master Nov 23, 2021
@nboisteault nboisteault deleted the geojson_style branch November 23, 2021 10:33
@jahow
Copy link
Member

jahow commented Nov 23, 2021

All good! I'll probably release a new version soon with this improvement, let me know if you intend to make other contributions that could be included as well. Thanks!

@nboisteault
Copy link
Contributor Author

I might make other contributions when I'll work on printing in Lizmap but I'll do that by the end of the year or begin of 2022. I'd like a new release when possible. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants