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

feat(search): datasource search source #45

Merged
merged 1 commit into from
May 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/demo-app/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
[placeholder]="'Location' | translate"
[decimals]="8"
[readonly]="false"
[layers]="map.layers$ | async"
[layers]="(map.layers$ | async) | clone"
[view]="contextService.context$.value ? (contextService.context$ | async).map.view : undefined">
</igo-map-field>
</div>
Expand Down
32 changes: 27 additions & 5 deletions src/demo-app/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';

import { ContextService, Feature, FeatureService, IgoMap,
LanguageService, MessageService, OverlayService,
ToolService } from '../../lib';
import { ContextService,
Feature, FeatureType, FeatureService, IgoMap,
LanguageService, LayerService, MapService, MessageService,
OverlayService, ToolService } from '../../lib';

import { AnyDataSourceOptions, DataSourceService } from '../../lib/datasource';


@Component({
selector: 'igo-demo',
Expand All @@ -21,7 +25,10 @@ export class AppComponent implements OnInit {
}

constructor(public contextService: ContextService,
public dataSourceService: DataSourceService,
public featureService: FeatureService,
public layerService: LayerService,
public mapService: MapService,
public messageService: MessageService,
public overlayService: OverlayService,
public toolService: ToolService,
Expand Down Expand Up @@ -52,11 +59,26 @@ export class AppComponent implements OnInit {
}

handleFeatureFocus(feature: Feature) {
this.overlayService.setFeatures([feature], 'move');
if (feature.type === FeatureType.Feature) {
this.overlayService.setFeatures([feature], 'move');
}
}

handleFeatureSelect(feature: Feature) {
this.overlayService.setFeatures([feature], 'zoom');
if (feature.type === FeatureType.Feature) {
this.overlayService.setFeatures([feature], 'zoom');
} else if (feature.type === FeatureType.DataSource) {
const map = this.mapService.getMap();

if (map !== undefined) {
this.dataSourceService
.createAsyncDataSource(feature.properties as AnyDataSourceOptions)
.subscribe(dataSource => {
map.addLayer(
this.layerService.createLayer(dataSource, feature.properties));
});
}
}
}

clearFeature() {
Expand Down
2 changes: 2 additions & 0 deletions src/demo-app/app/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RouterModule } from '@angular/router';
import { IgoModule, provideSearchSourceOptions,
provideIChercheSearchSource,
provideNominatimSearchSource,
provideDataSourceSearchSource,
LanguageLoader, provideLanguageService,
provideContextServiceOptions } from '../../lib';

Expand Down Expand Up @@ -35,6 +36,7 @@ export function translateLoader(http: Http) {
}),
provideNominatimSearchSource(),
provideIChercheSearchSource(),
provideDataSourceSearchSource(),
provideContextServiceOptions({
basePath: './contexts',
contextListFile: '_contexts.json'
Expand Down
3 changes: 1 addition & 2 deletions src/lib/feature/shared/feature.enum.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
export enum FeatureType {
Layer = <any> 'Layer',
DataSource = <any> 'DataSource',
Feature = <any> 'Feature',
Record = <any> 'Record'
}

export enum FeatureFormat {
WMS,
GeoJSON,
JSON
}
2 changes: 1 addition & 1 deletion src/lib/feature/shared/feature.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export interface Feature {
id: string;
source: string;
type: FeatureType;
format: FeatureFormat;
title: string;
format?: FeatureFormat;
title_html?: string;
icon?: string;

Expand Down
1 change: 1 addition & 0 deletions src/lib/map/shared/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export class IgoMap {

removeLayer(layer: Layer) {
const index = this.getLayerIndex(layer);

if (index >= 0) {
this.olMap.removeLayer(layer.olLayer);
this.layers.splice(index, 1);
Expand Down
83 changes: 83 additions & 0 deletions src/lib/search/search-sources/datasource-search-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Inject } from '@angular/core';
import { Jsonp, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import { Message } from '../../core/message';
import { Feature, FeatureType } from '../../feature';

import { SEARCH_SOURCE_OPTIONS, SearchSource } from './search-source';
import { SearchSourceOptions } from './search-source.interface';


export function dataSourceSearchSourcesFactory(jsonp: Jsonp, options: any) {
return new DataSourceSearchSource(jsonp, options);
}

export function provideDataSourceSearchSource() {
return {
provide: SearchSource,
useFactory: dataSourceSearchSourcesFactory,
multi: true,
deps: [Jsonp, SEARCH_SOURCE_OPTIONS]
};
}


export class DataSourceSearchSource extends SearchSource {

static _name: string = 'Data Sources';
static searchUrl: string = 'http://spssogl19d.sso.msp.gouv.qc.ca/igo2/api/layers/search';

constructor(private jsonp: Jsonp,
@Inject(SEARCH_SOURCE_OPTIONS)
private options: SearchSourceOptions) {
super();

this.options = options ? options : {};
}

getName(): string {
return DataSourceSearchSource._name;
}

search(term?: string): Observable<Feature[] | Message[]> {
const search = this.getSearchParams(term);

return this.jsonp
.get(DataSourceSearchSource.searchUrl, { search })
.map(res => this.extractData(res));
}

private extractData(response: Response): Feature[] {
return response.json().items.map(this.formatResult);
}

private getSearchParams(term: string): URLSearchParams {
const search = new URLSearchParams();
const limit = this.options.limit === undefined ? 5 : this.options.limit;

search.set('q', term);
search.set('limit', String(limit));
search.set('callback', 'JSONP_CALLBACK');

return search;
}

private formatResult(result: any): Feature {
return {
id: result.id,
source: DataSourceSearchSource._name,
type: FeatureType.DataSource,
title: result.source.title,
title_html: result.highlight.title,
icon: result.source.type === 'Layer' ? 'layers' : 'map',
properties: Object.assign({}, result.source, {
type: result.source.format,
params: {
layers: result.source.name
}
})
};
}

}
10 changes: 5 additions & 5 deletions src/lib/search/search-sources/icherche-search-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@ export class IChercheSearchSource extends SearchSource {
this.options = options ? options : {};
}

getName (): string {
getName(): string {
return IChercheSearchSource._name;
}

search (term?: string): Observable<Feature[] | Message[]> {
search(term?: string): Observable<Feature[] | Message[]> {
const search = this.getSearchParams(term);

return this.jsonp
.get(IChercheSearchSource.searchUrl, {search})
.map(res => this.extractData(res));
}

private extractData (response: Response): Feature[] {
private extractData(response: Response): Feature[] {
return response.json().features.map(this.formatResult);
}

private getSearchParams (term: string): URLSearchParams {
private getSearchParams(term: string): URLSearchParams {
const search = new URLSearchParams();
const limit = this.options.limit === undefined ? 5 : this.options.limit;

Expand All @@ -63,7 +63,7 @@ export class IChercheSearchSource extends SearchSource {
return search;
}

private formatResult (result: any): Feature {
private formatResult(result: any): Feature {
return {
id: result._id,
source: IChercheSearchSource._name,
Expand Down
1 change: 1 addition & 0 deletions src/lib/search/search-sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './search-source';
export * from './search-source.interface';
export * from './nominatim-search-source';
export * from './icherche-search-source';
export * from './datasource-search-source';
10 changes: 5 additions & 5 deletions src/lib/search/search-sources/nominatim-search-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ export class NominatimSearchSource extends SearchSource {
this.options = options ? options : {};
}

getName (): string {
getName(): string {
return NominatimSearchSource._name;
}

search (term?: string): Observable<Feature[] | Message[]> {
search(term?: string): Observable<Feature[] | Message[]> {
const search = this.getSearchParams(term);

return this.http
.get(NominatimSearchSource.searchUrl, { search })
.map(res => this.extractData(res));
}

private extractData (response: Response): Feature[] {
private extractData(response: Response): Feature[] {
return response.json().map(this.formatResult);
}

private getSearchParams (term: string): URLSearchParams {
private getSearchParams(term: string): URLSearchParams {
const search = new URLSearchParams();
const limit = this.options.limit === undefined ? 5 : this.options.limit;

Expand All @@ -63,7 +63,7 @@ export class NominatimSearchSource extends SearchSource {
return search;
}

private formatResult (result: any): Feature {
private formatResult(result: any): Feature {
return {
id: result.place_id,
source: NominatimSearchSource._name,
Expand Down
8 changes: 8 additions & 0 deletions src/lib/shared/clone/clone.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ClonePipe } from './clone.pipe';

describe('ClonePipe', () => {
it('create an instance', () => {
const pipe = new ClonePipe();
expect(pipe).toBeTruthy();
});
});
18 changes: 18 additions & 0 deletions src/lib/shared/clone/clone.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'clone'
})
export class ClonePipe implements PipeTransform {

transform(value: any, args?: any): any {
if (value === undefined) { return value; }

if (value instanceof Array) {
return value.map(obj => Object.assign(Object.create(obj), obj));
} else {
return Object.assign(Object.create(value), value);
}
}

}
1 change: 1 addition & 0 deletions src/lib/shared/clone/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './clone.pipe';
4 changes: 4 additions & 0 deletions src/lib/shared/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { TranslateModule } from '@ngx-translate/core';

import { ClickoutDirective } from './clickout';
import { CollapsibleComponent, CollapseDirective } from './collapsible';
import { ClonePipe } from './clone';
import { KeyvaluePipe } from './keyvalue';
import { ListComponent, ListItemDirective } from './list';
import { PanelComponent } from './panel';
Expand All @@ -34,6 +35,7 @@ import { SidenavShimDirective } from './sidenav';
ClickoutDirective,
CollapsibleComponent,
CollapseDirective,
ClonePipe,
KeyvaluePipe,
ListComponent,
ListItemDirective,
Expand All @@ -44,6 +46,7 @@ import { SidenavShimDirective } from './sidenav';
ClickoutDirective,
CollapsibleComponent,
CollapseDirective,
ClonePipe,
KeyvaluePipe,
ListComponent,
ListItemDirective,
Expand All @@ -62,6 +65,7 @@ export class IgoSharedModule {

export * from './collapsible';
export * from './clickout';
export * from './clone';
export * from './keyvalue';
export * from './list';
export * from './panel';
Expand Down
4 changes: 4 additions & 0 deletions src/lib/tool/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { NgModule, ModuleWithProviders } from '@angular/core';

import { IgoSharedModule } from '../shared';
import { IgoContextModule } from '../context/module';
import { IgoDataSourceModule } from '../datasource';
import { IgoFeatureModule } from '../feature';
import { IgoFilterModule } from '../filter';
import { IgoLayerModule } from '../layer';
import { IgoMapModule } from '../map';
import { IgoPrintModule } from '../print';

import { ToolService } from './shared';
Expand All @@ -28,9 +30,11 @@ const IGO_TOOLS = [
imports: [
IgoSharedModule,
IgoContextModule,
IgoDataSourceModule,
IgoFeatureModule,
IgoFilterModule,
IgoLayerModule,
IgoMapModule,
IgoPrintModule
],
exports: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';


import { IgoCoreModule } from '../../../core';
import { IgoSharedModule } from '../../../shared';
import { IgoFeatureModule } from '../../../feature';
import { IgoOverlayModule } from '../../../overlay';
import { IgoDataSourceModule } from '../../../datasource';
import { IgoLayerModule } from '../../../layer';
import { IgoMapModule } from '../../../map';

import { SearchResultsToolComponent } from './search-results-tool.component';

Expand All @@ -14,12 +19,17 @@ describe('SearchResultsToolComponent', () => {
TestBed.configureTestingModule({
imports: [
IgoSharedModule,
IgoCoreModule.forRoot(),
IgoFeatureModule.forRoot(),
IgoOverlayModule.forRoot()
IgoOverlayModule.forRoot(),
IgoDataSourceModule.forRoot(),
IgoMapModule.forRoot(),
IgoLayerModule.forRoot()
],
declarations: [
SearchResultsToolComponent
]
],
providers: []
})
.compileComponents();
}));
Expand Down
Loading