Skip to content

Commit

Permalink
Merge pull request #295 from yagajs/yaga-layer-provider
Browse files Browse the repository at this point in the history
Implement providers and layers control
  • Loading branch information
OpenSteveMap committed Dec 9, 2017
2 parents 4e9b4f5 + eebcdf4 commit 316a6db
Show file tree
Hide file tree
Showing 53 changed files with 1,074 additions and 349 deletions.
1 change: 1 addition & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ <h4>Icons</h4>
<h4>Controls</h4>
<ul class="list-group">
<li class="list-group-item"><a href="./attribution-control-directive">Attribution-Control-Directive</a></li>
<li class="list-group-item"><a href="./layers-control-directive">Layers-Control-Directive</a></li>
<li class="list-group-item"><a href="./scale-control-directive">Scale-Control-Directive</a></li>
<li class="list-group-item"><a href="./zoom-control-directive">Zoom-Control-Directive</a></li>
</ul>
Expand Down
17 changes: 17 additions & 0 deletions examples/layers-control-directive/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>YAGA | leaflet-ng2 | Layers-Control Example</title>
<script src="bundle.js"></script>
<link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap-theme.min.css" />
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" href="../../node_modules/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="../default.css" />
</head>
<body>
<app></app>
</body>
</html>
95 changes: 95 additions & 0 deletions examples/layers-control-directive/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Shims
import 'reflect-metadata';
import 'zone.js';

import { YagaModule } from '../../lib/index'; // @yaga/leflet-ng2

import { Component, PlatformRef } from '@angular/core';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { ExampleAppComponentBlueprint, IExampleProperties } from '../app-component-blueprint';
import { ExamplePropertiesModule, PROPERTIES_WRAPPER } from '../property.component';

const platform: PlatformRef = platformBrowserDynamic();

/* tslint:disable:max-line-length */
const template: string = `
<example-header [title]="'Layers-Control-Directive'"></example-header>
<div class="container">
<div class="map">
<yaga-map [zoom]="3">
<yaga-layers-control
(click)="handleEvent('click', $event);"
(dblclick)="handleEvent('dblclick', $event);"
(mousedown)="handleEvent('mousedown', $event);"
(mouseup)="handleEvent('mouseup', $event);"
(mouseover)="handleEvent('mouseover', $event);"
(mouseout)="handleEvent('mouseout', $event);"
(mousemove)="handleEvent('mousemove', $event);"
(positionChange)="handleEvent('positionChange', $event);"
(displayChange)="handleEvent('displayChange', $event);"
[(display)]="getDuplexPropertyByName('display').value"
[position]="getInputPropertyByName('position').value"
[opacity]="getInputPropertyByName('opacity').value"
>
<yaga-tile-layer yaga-base-layer="OSM" [url]="'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'"></yaga-tile-layer>
<yaga-tile-layer yaga-base-layer="OTM" [url]="'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'"></yaga-tile-layer>
<yaga-circle-marker yaga-overlay-layer="Marker" [lat]="51" [lng]="7"></yaga-circle-marker>
</yaga-layers-control>
</yaga-map>
</div>
${ PROPERTIES_WRAPPER }
</div><!-- /.container -->
<example-footer></example-footer>
`;
/* tslint:enable */

@Component({
selector: 'app',
template,
})
export class AppComponent extends ExampleAppComponentBlueprint {
public properties: IExampleProperties = {
duplex: [
{name: 'display', value: true, type: 'checkbox' },
],
input: [
{name: 'opacity', value: 0.8, type: 'relative'},{
additional: { states: ['topleft', 'topright', 'bottomleft', 'bottomright']},
name: 'position',
type: 'select',
value: 'topright',
},
],
output: [
{name: 'click', value: '', type: 'event' },
{name: 'dblclick', value: '', type: 'event' },
{name: 'mousedown', value: '', type: 'event' },
{name: 'mouseup', value: '', type: 'event' },
{name: 'mouseover', value: '', type: 'event' },
{name: 'mouseout', value: '', type: 'event' },
{name: 'mousemove', value: '', type: 'event' },
{name: 'positionChange', value: '', type: 'event' },
{name: 'displayChange', value: '', type: 'event' },
],
};
}

/* tslint:disable:max-classes-per-file */
@NgModule({
bootstrap: [ AppComponent ],
declarations: [ AppComponent ],
imports: [ BrowserModule, FormsModule, YagaModule, ExamplePropertiesModule ],
})
export class AppModule { }

document.addEventListener('DOMContentLoaded', () => {
platform.bootstrapModule(AppModule);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test": "npm run lint && npm run transpile && istanbul cover _mocha -- -- test/*.js",
"browser-test": "npm run transpile; browserify test/index.js -o browser-test/bundle.js",
"doc": "typedoc --out ./typedoc/ --mode file ts/",
"build-examples": "set -x && npm run transpile && cd examples && tsc; browserify tile-layer-directive/index.js -o tile-layer-directive/bundle.js && browserify map-component/index.js -o map-component/bundle.js && browserify zoom-control-directive/index.js -o zoom-control-directive/bundle.js && browserify scale-control-directive/index.js -o scale-control-directive/bundle.js && browserify attribution-control-directive/index.js -o attribution-control-directive/bundle.js && browserify circle-marker-directive/index.js -o circle-marker-directive/bundle.js && browserify image-overlay-directive/index.js -o image-overlay-directive/bundle.js && browserify icon-directive/index.js -o icon-directive/bundle.js && browserify div-icon-directive/index.js -o div-icon-directive/bundle.js && browserify passau/index.js -o passau/bundle.js && browserify circle-directive/index.js -o circle-directive/bundle.js && browserify marker-directive/index.js -o marker-directive/bundle.js && browserify floor-plan/index.js -o floor-plan/bundle.js"
"build-examples": "set -x && npm run transpile && cd examples && tsc; browserify tile-layer-directive/index.js -o tile-layer-directive/bundle.js && browserify map-component/index.js -o map-component/bundle.js && browserify zoom-control-directive/index.js -o zoom-control-directive/bundle.js && browserify layers-control-directive/index.js -o layers-control-directive/bundle.js && browserify scale-control-directive/index.js -o scale-control-directive/bundle.js && browserify attribution-control-directive/index.js -o attribution-control-directive/bundle.js && browserify circle-marker-directive/index.js -o circle-marker-directive/bundle.js && browserify image-overlay-directive/index.js -o image-overlay-directive/bundle.js && browserify icon-directive/index.js -o icon-directive/bundle.js && browserify div-icon-directive/index.js -o div-icon-directive/bundle.js && browserify passau/index.js -o passau/bundle.js && browserify circle-directive/index.js -o circle-directive/bundle.js && browserify marker-directive/index.js -o marker-directive/bundle.js && browserify floor-plan/index.js -o floor-plan/bundle.js"
},
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ require('../lib/circle-marker.directive.spec');
require('../lib/zoom-control.directive.spec');
require('../lib/attribution-control.directive.spec');
require('../lib/scale-control.directive.spec');
require('../lib/layers-control.directive.spec');
11 changes: 8 additions & 3 deletions ts/attribution-control.directive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { expect } from 'chai';
import { point } from 'leaflet';

import {
AttributionControlDirective,
ControlPosition,
LayerGroupProvider,
MapComponent,
MapProvider,
} from './index';
import { randomNumber } from './spec';

describe('Attribution-Control Directive', () => {
let map: MapComponent;
let control: AttributionControlDirective;
beforeEach(() => {
map = new MapComponent({nativeElement: document.createElement('div')});
map = new MapComponent(
{nativeElement: document.createElement('div')},
new LayerGroupProvider(),
new MapProvider(),
);
(map as any)._size = point(100, 100);
(map as any)._pixelOrigin = point(50, 50);
control = new AttributionControlDirective(map);
control = new AttributionControlDirective({ ref: map });
});

describe('[(display)]', () => {
Expand Down
7 changes: 3 additions & 4 deletions ts/attribution-control.directive.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
Directive,
EventEmitter,
forwardRef,
Inject,
Input,
OnDestroy,
Output,
Expand All @@ -15,6 +13,7 @@ import { Control,
} from 'leaflet';
import { ATTRIBUTION_PREFIX } from './consts';
import { MapComponent } from './map.component';
import { MapProvider } from './map.provider';
import { enhanceMouseEvent } from './mouse-event-helper';

/**
Expand Down Expand Up @@ -124,10 +123,10 @@ export class AttributionControlDirective extends Control.Attribution implements
@Output('mouseout') public mouseoutEvent: EventEmitter<LeafletMouseEvent> = new EventEmitter();

constructor(
@Inject(forwardRef(() => MapComponent)) mapComponent: MapComponent,
mapProvider: MapProvider,
) {
super({prefix: ATTRIBUTION_PREFIX});
mapComponent.addControl(this);
mapProvider.ref.addControl(this);

// Events
this.getContainer().addEventListener('click', (event: MouseEvent) => {
Expand Down
50 changes: 50 additions & 0 deletions ts/base-layer.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
Attribute,
Directive,
OnDestroy,
} from '@angular/core';
import { LayerProvider } from './layer.provider';
import { LayersControlProvider } from './layers-control.provider';

/**
* Angular2 directive for adding layers to the layers-control of Leaflet as base-layer.
*
* *You can use this directive in an Angular2 template after importing `YagaModule`.*
*
* How to use in a template:
* ```html
* <yaga-map>
* <yaga-layers-control>
* <!-- This can be any other layer... -->
* <yaga-tile-layer yaga-base-layer="OSM"></yaga-tile-layer>
* </yaga-attribution-control>
* </yaga-map>
* ```
*
* @link http://leafletjs.com/reference-1.2.0.html#control-layers-addbaselayer Original Leaflet documentation
* @link https://leaflet-ng2.yagajs.org/latest/browser-test?grep=Base-Layer%20Directive Unit-Test
* @link https://leaflet-ng2.yagajs.org/latest/coverage/lcov-report/lib/base-layer.directive.js.html
* Test coverage
* @link https://leaflet-ng2.yagajs.org/latest/typedoc/classes/baselayerdirective.html API documentation
* @example https://leaflet-ng2.yagajs.org/latest/examples/layers-control-directive/
*/
@Directive({
selector: '[yaga-base-layer]',
})
export class BaseLayerDirective implements OnDestroy {
constructor(
// TODO: Inject LayersControl @Inject(forwardRef(() => LayersControl)) protected layersControl: LayersControl,
protected layer: LayerProvider,
@Attribute('yaga-base-layer') public readonly name: string,
public layersControlProvider: LayersControlProvider,
) {
this.layersControlProvider.ref.addBaseLayer(this.layer.ref, name);
}

/**
* Internal method to provide the removal from the control in Leaflet, when removing it from the Angular template
*/
public ngOnDestroy(): void {
this.layersControlProvider.ref.removeLayer(this.layer.ref);
}
}
27 changes: 14 additions & 13 deletions ts/circle-marker.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
CircleMarkerDirective,
LatLng,
LatLngExpression,
LayerGroupProvider,
MapComponent,
MapProvider,
PopupDirective,
TooltipDirective,
} from './index';
Expand All @@ -26,12 +28,16 @@ describe('Circle-Marker Directive', () => {
type: 'Feature',
};
beforeEach(() => {
map = new MapComponent({nativeElement: document.createElement('div')});
map = new MapComponent(
{nativeElement: document.createElement('div')},
new LayerGroupProvider(),
new MapProvider(),
);
(map as any)._size = point(100, 100);
(map as any)._pixelOrigin = point(50, 50);
(map as any)._renderer = (map as any)._renderer || new SVG();

layer = new CircleMarkerDirective<any>(map);
layer = new CircleMarkerDirective<any>({ ref: map }, {} as any);
layer.ngAfterContentInit();
});

Expand Down Expand Up @@ -286,7 +292,7 @@ describe('Circle-Marker Directive', () => {
test: 'OK',
};
beforeEach(() => {
layerWithProps = new CircleMarkerDirective<any>(map);
layerWithProps = new CircleMarkerDirective<any>({ ref: map }, {} as any);
});
it('should be changed in Leaflet when changing in Angular', () => {
layerWithProps.properties = TEST_OBJECT;
Expand Down Expand Up @@ -447,10 +453,8 @@ describe('Circle-Marker Directive', () => {

beforeEach(() => {
testDiv = document.createElement('div');
popup = new PopupDirective(map, { nativeElement: testDiv });

// Hack to get write-access to readonly property
layer = Object.create(new CircleMarkerDirective<any>(map), { popupDirective: {value: popup} });
layer = new CircleMarkerDirective<any>({ ref: map }, {} as any);
popup = new PopupDirective({ nativeElement: testDiv }, { ref: layer });
});
it('should bind popup', () => {
layer.ngAfterContentInit();
Expand All @@ -463,21 +467,18 @@ describe('Circle-Marker Directive', () => {
let testDiv: HTMLElement;
beforeEach(() => {
testDiv = document.createElement('div');
tooltip = new TooltipDirective(map, { nativeElement: testDiv });

// Hack to get write-access to readonly property
layer = Object.create(new CircleMarkerDirective<any>(map), { tooltipDirective: {value: tooltip} });
layer = new CircleMarkerDirective<any>({ ref: map }, {} as any);
tooltip = new TooltipDirective({ ref: layer }, { nativeElement: testDiv });
});
it('should bind tooltip', () => {
layer.ngAfterContentInit();
expect((layer as any)._tooltip).to.equal(tooltip);
});
});

describe('Destroying a Circle Directive', () => {
before(() => {
// Hack to get write-access to readonly property
layer = new CircleMarkerDirective<any>(map);
layer = new CircleMarkerDirective<any>({ ref: map }, {} as any);
});
it('should remove Circle Directive from map on destroy', () => {
expect(map.hasLayer(layer)).to.equal(true);
Expand Down

0 comments on commit 316a6db

Please sign in to comment.