Giter Club home page Giter Club logo

ol-ext-angular's Introduction

  ol-ext + Angular

This project is an example to use Openlayers and ol-ext with Angular 7.

It is by no means a complete app but you should find mecanisms to handle an Openlayers map using Angular, with interactions and controls to customize for your own.

Goal

The goal of this example is to create a map as simple as that:

<app-map id="map">
  <!-- Add a layers -->
  <app-layer layer="OSM" opacity=.5 visibility=true></app-layer>
  <app-layer layer="watermark" visibility=false></app-layer>
  <!-- Add interactions -->
  <app-interaction1></app-interaction1>
  <app-interaction2></app-interaction2>
  <!-- Add a controls inside the map -->
  <app-control1></app-control1>
  <app-control2></app-control2>
</app-map>

As controls can be set outside the map (using the target option) we also want to have this option too.

<app-map id="map">
  <!-- Add a layers -->
  <app-layer layer="OSM" opacity=.5 visibility=true></app-layer>
  <!-- Add a controls inside the map -->
  <app-control1></app-control1>
</app-map>

<!-- Add control outside -->
<app-control2 mapId="map"></app-control2>

We also want to create more than one map:

<app-map id="map">
  <!-- Add a layers -->
  <app-layer layer="OSM" opacity=.5 visibility=true></app-layer>
</app-map>

<app-map id="map2">
  <!-- Add a layers -->
  <app-layer layer="watermark"></app-layer>
</app-map>

Mecanisms

MapService and MapidService

The map is implemented as a service to let you access it in other components.

Getting a map

You just have to declare the service in your constructor to access the map:

constructor(private mapService: MapService) { }

Then to retrieve the map you want, use the getMap method:

// Default map (id=map)
const map = mapService.getMap();
// another map (id=map1)
const map1 = mapService.getMap('map1');

The parameter is the id of the map you want to get. If you just have one map you can use the default value (map).

Getting the current map

The MapidService let you handle the current map's id. It is used by the map component to register a new map id (mapServe.setId()). It's not a root service and each map has its own one, thus each component defined inside a map component can access the current map id using the getId() method of the service.

This id is registered by the root MapComponent (using the setId()method).

Customizing the map

Feel free to modify the createMap() method of the MapService to handle the default map.
The MapComponent let you define the map itself. Use the ngOnInit() method to customize the map (set zoom, etc.).

Creating new map components (controls, layers, interactions...)

This example comes with a set of components for each Openlayers map features: controls, interactions, layer...
Just copy the .ts file to create a new one to use in your app.

You first have to declare the services in your constructor:

  constructor(
    private mapService: MapService,
    @Host()
    private mapidService: MapidService
  ) { }

Then in ngOnInit, get the current map like this:

  ngOnInit() {
    // Get the current map
    const map: OlMap = this.mapService.getMap(this.mapidService);
    // Add component to the map
  }

To let the control be set inside or outside the map you also need to get the target ElementRef. In this case the MapidService is optional (as it comes inside a MapComponent it is not defined when set outside a map). Look at the ControlComponent for more informations.

Example

The example defines:

  • 2 maps
  • a set of layers define using a component propertie
  • an interaction to synchonize the maps together
  • a control inside the map (Bookmark contol)
  • a control outside the map (MousePosition).

Build

This project was generated with Angular CLI version 7.1.4.

Install

Run npm install to install node modules and start developping.

Development server

Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

Further help

To get more help on the Angular CLI use ng help or go check out the Angular CLI README.

ol-ext-angular's People

Contributors

viglino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ol-ext-angular's Issues

controlcomponent - should `this.mapService.getMap(this.mapidService)` be `this.mapService.getMap(this.mapidService.getId())` instead?

I am not 100% sure about this, but, as I am using your examples in this repo (a LOT actually, thanks!), I came across this line of code inside control.component.ts:

const map: OlMap = this.mapService.getMap(this.mapidService || this.mapId);

Shouldn't it be:

const map: OlMap = this.mapService.getMap(this.mapidService.getId() || this.mapId);

?

Anyway, big thanks for sharing this repo!!!

Can a custom control be used with multiple maps?

Sorry to bother again...
hope you can help, otherwise, please feel free to ignore this message.

I am interested in adding a custom control outside my maps as you did with app-mouse-position.
My goal is to have a single control that can be used with multiple maps to (e.g.) list the number of layers wthin the clicked map somewhere. This control will be placed in a target outside the maps.

However, am I supposed to add it to use setMap() upon creation, or shall I simply define it and use it when I need it?

I see from your app-component.html that you define your app-mouse-postion twice, once with a mapId attribute and once without. May I ask you why? I would be interested in how the one without mapId could be used for my case.

<!-- Define control outside the map -->
<app-mouse-position></app-mouse-position>
<app-mouse-position mapId="map1"></app-mouse-position>

I think my main problem is that I will have to switch map in my control with setMap() every time I click on a different map, while in your example I guess the mouse coordinates can be taken from either of the two maps as they are in sync, am I correct?

Not getting vector layer displayed on map

Hi, I tried to add some marker points using this example but after generating a vector layer with a feature layer map doesn't display any marker or text at all maybe I missed something very crucial while doing this code.

where I am moderating the following code

in app-layer-component added
these two code in ngoninit hook
case 'marker': { layer = new l.Vector({ source: this.markerVSource }); break; }

if (this.layer == 'marker') { const features = this.mapService.olPtsLayer() const mStyle = this.mapService.markerStyle(); this.markerVSource.addFeatures(features) layer.setStyle(mStyle) layer.setVisible(this.visibility); layer.setOpacity(this.opacity); console.log(this.markerVSource.getFeatures()) }

this declaration as a property
markerVSource = new s.Vector({ features: [], attributions: 'National UFO Reporting Center', });
and the rest code is exactly the same.
also, I tried to console log the feature layer after adding it to the map which shows the layer has been added but non of the markers appears. Tried testing its icon styles is at a valid path!
can you guide me on how can I add a marker using the app-layer-component
image

Storymap with angular

Congratulations for this great contribution. Do you have an example storymap with angular?

Thank you.

Save Vector layer on completion of draw

Hi,
I have built on top of this example to add an Editbar to draw shapes into a vector layer. This has been done by adding to the control component example.

I have also added a MapdataService to handle the updating of these geographical features with an aim of sending the updated data as a GeoJSON to another part of the application for storing and later reloading. I think this is nearly there but it is unclear to me how to detect the updated shape can be signaled to the service in order to add to the observable subject which the service handles.

Basically my strategy is to call updateData() in the MapdataService with the appropriate data sending the entire vector layer each time a shape completion or deletion has taken place. What I am unclear upon is how to detect that the vector has been updated and then access its geography.

There is a stackblitz here with my code example:

https://stackblitz.com/edit/ol-ext-angular-extend?file=src%2Fapp%2Fmap%2Fmapdata.service.ts

Thanks,

Paul

Styling custom controls

Hello, and again thanks for this repo.

I would appreciate your help if you can answer.

I am having serious troubles in understanding how should I style a custom control.

I have defined my custom control like this:

sync-control.ts

import Control from 'ol/control/Control';

export class SyncControl extends Control {
    constructor() {
        const button = document.createElement('button');

        const element = document.createElement('div');
        element.className = 'sync-control';
        element.appendChild(button);

        super( { element } );
    }
}

sync-control.component.ts

import { Component, OnInit, Host } from '@angular/core';

import { MapService } from '../../map.service';
import { MapidService } from '../../mapid.service';
import { Map } from 'ol';
import { SyncControl } from './sync-control';

@Component({
  selector: 'app-sync-control',
  templateUrl: './sync-control.component.html',
  styleUrls: ['./sync-control.component.css']
})
export class SyncControlComponent implements OnInit {

  constructor(
    private mapService: MapService,
    @Host()
    private mapidService: MapidService) { }

  ngOnInit(): void {
    // Get the current map
    const map: Map = this.mapService.getMap(this.mapidService.getId());
    const control = new SyncControl();
    map.addControl(control);
  }

}

sync-control.component.css

.sync-button {
    background-color: blue;
}

app.component.html

<div class="map-wrapper">
    <div class="map-item">
        <h4>Origin</h4>
        <app-map id="origin" class="map">
            <app-sync-control></app-sync-control>
            <app-layer name="overlay"></app-layer>
        </app-map>
    </div>
</div>

I can see the control in the map, however, I cannot style it.

I also tried with inline style (i.e. <app-sync-control style="background-color: blue;">), but neither that worked.

Cannot display imageLayer without setting position:fixed in css

I am trying to follow the mechanisms to use openlayer in angular, and I want to display an image in the map using imageLayer, but the layer will be set as dispaly:none unless I set the app-map to position: fixed in css. Is there any way to not use position:fixed for the map?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.