Geometry Drawing tools using Angular Cesium

Eitan Frailich
May 7, 2020 · 5 min read

In this short blog post, we will learn how to use and customize geometry editors for CesiumJS using angular-cesium.

Angular-cesium is an open-source library that combines the awesome power of CesiumJS as a map engine and Angular as a front end framework.
If you are not familiar with angular-cesium then check out this blog post.

What are Geometry editors?

A common feature in a GIS application is the ability to create/edit geographical entities such as polygons, polylines, etc. As we are working with Cesium we also want to draw entities on 3D models and world terrain.

angular-cesium has an easy and intuitive service for doing exactly that. The supported shape editors are:

  • CirclesEditorService - For drawing circles

How to use it

To learn how to use the editors, we will create a small angular application that implements a polygon selection tool.

Initialization

  • Create a new Angular project using Angular CLI:
ng new my-shape-drawer
  • Add angular-cesium:
ng add angular-cesium

ng add will install and configure angular-cesium for you, for manual installation click here.

  • angular-cesium editors are a part of AngularCesiumWidgetsModule so we need to add it to our app.module.ts file:
@NgModule({
// ...
imports: [
AngularCesiumModule.forRoot(),
AngularCesiumWidgetsModule,
// ...
],
})
export class AppModule {}

Adding the geometry editor to our app

Each editor service work with an editor-component. Therefore you need to create an editor-componentfor each editor service. The component needs to be created somewhere inside <ac-map> (the main component for our cesium globe).

For the polygons editor service, we will add the <polygons-editor> in the app.component.html file:

<ac-map>
<polygons-editor></polygons-editor>
</ac-map>

Usually, we will create a dedicated component for handling the editor logic but for simplicity’s sake, we add the code in the main app.component.

Next, we need to provide the editor service, in our example PolygonEditorService . The editor service allows us to create() and edit() polygons.

@Component({
...
providers: [PolygonEditorService],
})
export class MyMapComponent {
editing$: PolygonEditorObservable; constructor(private polygonEditor: PolygonsEditorService) {} startDraw() {
this.editing$ = this.polygonEditor.create();
//// Or Edit from existing points
// const initialPos = [
// Cesium.Cartesian3.fromDegrees(20, 40),
// Cesium.Cartesian3.fromDegrees(45, 40),
// Cesium.Cartesian3.fromDegrees(30, 20)];
// this.editing$ = this.polygonEditor.edit(initialPos);
}
}

You can provide the service in the root module or if you wish to limit the service access, you can provide it anywhere lower in your component hierarchy.

All editors have a similar API, this example is relevant to all editors

Let’s add a simple button that will call our startDraw() :

<ac-map>
<polygons-editor></polygons-editor>
<button (click)="startDraw()" class="fixed-pos">Create</button>
</ac-map>

That’s it! now we have a polygon drawer ready to use. Try running your application and create your polygon:

Customization

Ok now we’ve created a polygon but what if we don’t like the default pale blue fill? No problem! the editors are fully customizable.
Let's change the default style so our polygon will look like a selection tool:

// create accepts PolygonEditOptions object
const editing$ = this.polygonsEditor.create({
pointProps: {
color: Cesium.Color.WHITE,
pixelSize: 10,
},
polygonProps: {
material: Cesium.Color.TRANSPARENT,
},
polylineProps: {
material: () => new Cesium.PolylineDashMaterialProperty()
}
});

Result:

The editor click events are configurable too. The default events are: click for adding points and double click for finish creating the shape. These events can be changed to whatever you’d like. Learn more about the different options here.

Controlling our editable geometry

All editors return a custom Observer object that allows us to subscribe to different shape actions and to manipulate our geometry from the code. For more details about the different options click here.

In our selection tool use case, we will use the dispose() method to delete the shape after it was created.
Then we will use a simple npm package calledpoint-in-polygon to determine if our entities are in the selected polygon area.

import pointInPolygon from 'point-in-polygon';startDraw() {
const polygon$ = this.polygonEditor.create( { //...options } );

polygon$.subscribe((editUpdate: PolygonEditUpdate) => {
if (editUpdate.editAction === EditActions.ADD_LAST_POINT)
// Remove the editable polygon
this.editing$.dispose();

// Find all entities in the polygon location
const polygonArr = this.editing$.getCurrentPoints()
.map(p => p.getPosition())
.map(cart => CoordinateConverter.cartesian3ToLatLon(cart))
.map(latLon => [latLon.lon, latLon.lat]);
const myEntities = this.store.getEntities();
myEntities.forEach(entity => {
console.log(pointInPolygon(entity.position, polygonArr));
// Or update the entity
});
}
});
}

The final result:

Recommended data flow

As we saw in the example, we can use the editors to create and edit entities. So, should we use it to display our geographical data? For example, a list of polygons we fetched from the server? The short answer is - No!
Editors services are used for creating editable entities, if you want to display regular entities you should use the normal ac-layer API.

So what will be the right flow when I want to create a new geographical entity in my app? The recommended flow will be:

  1. Create a geographical entity using the service editor.

This way your app will be consistent with the server and your architecture will remain flexible to support entity updates and creation of new entities.

Who we are?

We are Articode, a software development company that specializes in GIS systems. We love open-source and we are the creators and maintainers of angular-cesium.

Check out articode.co for more information and contact info.

Articode

Extraordinary software in a snap

Thanks to David Yahalomi and Daniel

Eitan Frailich

Written by

Software developer enthusiastic about open source and new technology. co-founder @ articode.co

Articode

Articode

Articode is the software development company providing you unparalleled innovation for enterprise-level software at start-up speed. Head over to our website more info.

Eitan Frailich

Written by

Software developer enthusiastic about open source and new technology. co-founder @ articode.co

Articode

Articode

Articode is the software development company providing you unparalleled innovation for enterprise-level software at start-up speed. Head over to our website more info.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store