Gestor de nuevos markers en proceso...

This commit is contained in:
Siroco 2018-09-22 00:03:53 +02:00
parent 48233010e7
commit 46d4c450a1
25 changed files with 1126 additions and 157 deletions

569
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,10 @@
"@angular/platform-browser": "^5.2.0", "@angular/platform-browser": "^5.2.0",
"@angular/platform-browser-dynamic": "^5.2.0", "@angular/platform-browser-dynamic": "^5.2.0",
"@angular/router": "^5.2.0", "@angular/router": "^5.2.0",
"@mapbox/mapbox-gl-geocoder": "^2.3.0",
"classlist.js": "1.1.20150312", "classlist.js": "1.1.20150312",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"mapbox-gl": "^0.49.0",
"rxjs": "^5.5.6", "rxjs": "^5.5.6",
"zone.js": "^0.8.19" "zone.js": "^0.8.19"
}, },

View File

@ -0,0 +1,40 @@
.container {
width:250px;
min-width:200px;
min-height:50px;
max-height:80vh;
overflow-y:auto;
background:rgba(0,0,0,0.8);
border:#fff solid 0px;
margin:20px;
color:#fff;
padding:30px 10px;
font-size:0.8em;
}
.container::before {
display: block;
position: absolute;
top: 15px;
right: 2.7rem;
width: 0;
height: 0;
border-right: 8px solid transparent;
border-bottom: 8px solid #333;
border-left: 8px solid transparent;
content: "";
z-index: 1000;
}
h1 { font-size:1em; }
button { font-family:'Raleway',sans-serif; background:transparent; padding:5px; width:100%; color:#fff; border:#fff solid 2px;}
button:hover {background:#fff;color:#000;cursor:pointer;}
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}

View File

@ -0,0 +1,33 @@
<div class="container" [hidden]="!appService.markers.length">
<div [hidden]="!submitted">
<p>Gracias por participar</p>
</div>
<div [hidden]="submitted">
<h1>Agrega un nuevo sonido</h1>
<p>Publica nuevos contenidos</p>
<h2>Coord: {{appService.markers}}</h2>
{{diagnostic}}
<form (ngSubmit)="onSubmit()" #documentForm="ngForm">
<div class="form-group">
<label for="title">Título</label>
<input type="text" id="title" [(ngModel)]="document.title" name="title" required/>
</div>
<div class="form-group">
<label for="author">Autor/a</label>
<input type="text" id="author" [(ngModel)]="document.author" name="author" required/>
</div>
<div class="form-group">
<label for="description">Descripción</label>
<textarea id="description" [(ngModel)]="document.description" name="description"></textarea>
</div>
<div class="form-group">
<label for="category">Categoría</label>
<select id="category" [(ngModel)]="document.category" name="category" required>
<option *ngFor="let cat of categories" [value]="cat">{{cat}}</option>
</select>
</div>
<button type="submit" [disabled]="!documentForm.form.valid">Envía</button>
<button type="button" (click)="appService.clearMarker()">Cancela</button>
</form>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AddContentComponent } from './add-content.component';
describe('AddContentComponent', () => {
let component: AddContentComponent;
let fixture: ComponentFixture<AddContentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddContentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddContentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
import { Component, OnInit } from '@angular/core';
import { Documento, GeoJson } from '../map';
import { AppService } from '../app.service';
@Component({
selector: 'add-content',
templateUrl: './add-content.component.html',
styleUrls: ['./add-content.component.css']
})
export class AddContentComponent implements OnInit {
categories = ['bioacustica', 'social', 'urbano', 'natural'];
document = new Documento(1,new GeoJson([0,0]),'', '', '', this.categories[0], '');
submitted = false;
constructor(public appService : AppService) {
console.log('onConstruct')
}
onSubmit() {
this.document.setCoord(this.appService.markers)
console.log(this.document);
this.submitted = false
}
ngOnInit() {
console.log('oninit')
this.document.setCoord(this.appService.markers)
}
get diagnostic() { return JSON.stringify(this.document) }
}

View File

@ -1,10 +1,11 @@
<app-messages></app-messages> <messages></messages>
<add-content></add-content>
<header> <header>
<soinu-progress *ngIf="!isMap"></soinu-progress> <soinu-progress *ngIf="!isMap"></soinu-progress>
</header> </header>
<section *ngIf="!isMap"> <section *ngIf="!isMap">
<h1>Construir a través del oído</h1> <h1>Construir a través del oído</h1>
<p>El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <b>Xabier Erkizia</b> y <b>Luca Rullo</b>, de la asociación <a href="https://www.audio-lab.org">AUDIOLAB</a>.</p> <p i18n="Texto intro">El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <b>Xabier Erkizia</b> y <b>Luca Rullo</b>, de la asociación <a href="https://www.audio-lab.org">AUDIOLAB</a>.</p>
<nav *ngIf="appService.acceptCookies"> <nav *ngIf="appService.acceptCookies">
<button pButton label="map" (click)="showMap()" title="Muestra el mapa">Mapa</button> <button pButton label="map" (click)="showMap()" title="Muestra el mapa">Mapa</button>
<button pButton label="listen" (click)="listenStream()" title="En directo">En directo</button> <button pButton label="listen" (click)="listenStream()" title="En directo">En directo</button>

View File

@ -1,5 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { GeojsonService } from './geojson.service';
import { Observable } from 'rxjs/Observable';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -9,8 +11,12 @@ import { AppService } from './app.service';
export class AppComponent { export class AppComponent {
title = 'Sartaguda suena'; title = 'Sartaguda suena';
isMap = false; isMap = false;
info: Observable<any>;
constructor(public appService: AppService) { } constructor(public appService: AppService,
public geojsonService: GeojsonService ) {
this.geojsonService.getData();
}
showMap() { showMap() {
this.isMap = true; this.isMap = true;

View File

@ -1,13 +1,17 @@
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { MapService } from './map.service'; import { MapService } from './map.service';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { GeojsonService } from './geojson.service';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { MapBoxComponent } from './map-box/map-box.component'; import { MapBoxComponent } from './map-box/map-box.component';
import { SoinuProgressComponent } from './soinu-progress/soinu-progress.component'; import { SoinuProgressComponent } from './soinu-progress/soinu-progress.component';
import { MessagesComponent } from './messages/messages.component'; import { MessagesComponent } from './messages/messages.component';
import { AddContentComponent } from './add-content/add-content.component';
@NgModule({ @NgModule({
@ -15,14 +19,18 @@ import { MessagesComponent } from './messages/messages.component';
AppComponent, AppComponent,
MapBoxComponent, MapBoxComponent,
SoinuProgressComponent, SoinuProgressComponent,
MessagesComponent MessagesComponent,
AddContentComponent
], ],
imports: [ imports: [
BrowserModule BrowserModule,
HttpClientModule,
FormsModule
], ],
providers: [ providers: [
MapService, MapService,
AppService AppService,
GeojsonService
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })

View File

@ -1,4 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { GeoJson } from './map';
@Injectable() @Injectable()
export class AppService { export class AppService {
@ -7,14 +8,24 @@ export class AppService {
acceptCookies: boolean = false; acceptCookies: boolean = false;
audioStreamingUrl = "http://irratia.zintzilik.net"; audioStreamingUrl = "http://irratia.zintzilik.net";
button: boolean = false; button: boolean = false;
markers: any[] = [];
constructor() { }
constructor() {}
add(message: string, button:boolean = false) { add(message: string, button:boolean = false) {
this.messages.push(message); this.messages.push(message);
this.button=button; this.button=button;
} }
addMarker(message: string, coord:any[]) {
this.markers = coord
console.log('new marker: '+coord)
}
clearMarker() {
this.markers = [];
}
clear() { clear() {
this.messages = []; this.messages = [];
this.acceptCookies = true; this.acceptCookies = true;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { GeojsonService } from './geojson.service';
describe('GeojsonService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [GeojsonService]
});
});
it('should be created', inject([GeojsonService], (service: GeojsonService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,43 @@
import { Injectable } from '@angular/core';
import { GeoJson, MARKERS } from './map';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import 'rxjs/add/operator/map';
@Injectable()
export class GeojsonService {
accessToken:string;
apiUrl:string;
constructor( private http: HttpClient) {
this.accessToken = '1245c38775ff9fd8b8a721e4fe7472ab5d06020f853f66c516f26eb96fb87235'
this.apiUrl = 'http://ca.ecouterlemonde.net/service.php/find/ca_objects'
}
getData() {
const data = {
"bundles" : {
"access" : { "convertCodesToDisplayText" : true },
"status" : { "convertCodesToDisplayText" : true },
"ca_entities.entity_id" : {"returnAsArray" : true }
}
}
const params = new HttpParams()
.set('authToken',this.accessToken)
.set('q','*')
.set('source',encodeURIComponent(JSON.stringify(data)))
console.log(encodeURIComponent(JSON.stringify(data)))
/*this.http.get(this.apiUrl, { params: params } )
.subscribe( resp=> {
console.log('.... data ...');
console.log(resp);
});*/
return of();
}
}

View File

@ -1,4 +1,5 @@
/*@import '../../../node_modules/@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';*/
.map { width:100%;height:100%; position:absolute; top:0; left:0;} .map { width:100%;height:100%; position:absolute; top:0; left:0;}
.mapboxgl-marker { width:30px;height:30px;background:#fff;} .mapboxgl-marker { width:30px;height:30px;background:#fff;}
.mapboxgl-marker { width:300px; height:300px; background:#fff !important; } .mapboxgl-marker { width:300px; height:300px; background:#fff !important; }
.marker-player { max-width:100%;} .marker-player { max-width:100%;}

View File

@ -3,6 +3,8 @@ import * as mapboxgl from 'mapbox-gl';
import { MapService } from '../map.service'; import { MapService } from '../map.service';
import { AppService } from '../app.service'; import { AppService } from '../app.service';
import { GeoJson, FeatureCollection} from '../map'; import { GeoJson, FeatureCollection} from '../map';
//import * as MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
@Component({ @Component({
selector: 'map-box', selector: 'map-box',
@ -23,8 +25,9 @@ export class MapBoxComponent implements OnInit {
markers: any; markers: any;
hoverid: null; hoverid: null;
activeMarker: any; activeMarker: any;
newMarker: any;
constructor( constructor(
private mapService: MapService, private mapService: MapService,
public appService: AppService public appService: AppService
) { } ) { }
@ -47,14 +50,26 @@ export class MapBoxComponent implements OnInit {
pitch: 60, // pitch in degrees pitch: 60, // pitch in degrees
bearing: 0, // bearing in degrees bearing: 0, // bearing in degrees
center: [this.lng, this.lat], center: [this.lng, this.lat],
attributionControl: {
compact: true,
customAttribution: "Developed by Audiolab"
}
}); });
// controls // controls
this.map.addControl(new mapboxgl.NavigationControl()) this.map.addControl(new mapboxgl.NavigationControl())
// this.map.addControl(new MapboxGeocoder({
// accessToken: mapboxgl.accessToken
// }));
let feed = "http://www.soinumapa.net/geojson/"
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.on('click','clusters', (event) => { this.map.on('click','clusters', (event) => {
let features = this.map.queryRenderedFeatures(event.point, { layers: ['clusters'] }); let features = this.map.queryRenderedFeatures(event.point, { layers: ['clusters'] });
@ -68,6 +83,24 @@ export class MapBoxComponent implements OnInit {
}) })
}) })
this.map.on('click',(event)=> {
if (this.newMarker!=undefined) this.newMarker.remove()
var features = this.map.queryRenderedFeatures(event.point, {layers:['clusters','soinumapa']});
//console.log(features);
if (features.length==0) {
var el = document.createElement('div');
el.className = 'marker new-marker';
const coordinates = [event.lngLat.lng, event.lngLat.lat]
// const newMarker = new GeoJson(coordinates, { message : 'new marker' })
this.appService.addMarker('new marker',coordinates)
this.newMarker = new mapboxgl.Marker(el)
.setLngLat(coordinates)
.addTo(this.map);
}
//console.log(event)
})
this.map.on('click','soinumapa', (event) => { this.map.on('click','soinumapa', (event) => {
// clean old markers // clean old markers
//let m = document.getElementsByClassName('active-marker') //let m = document.getElementsByClassName('active-marker')
@ -76,16 +109,18 @@ export class MapBoxComponent implements OnInit {
if (this.activeMarker!=undefined) this.activeMarker.remove() if (this.activeMarker!=undefined) this.activeMarker.remove()
const coordinates = [event.lngLat.lng, event.lngLat.lat] const coordinates = [event.lngLat.lng, event.lngLat.lat]
const newMarker = new GeoJson(coordinates, { message : 'new marker' }) //const newMarker = new GeoJson(coordinates, { message : 'new marker' })
//this.appService.addMarker('new marker',newMarker)
let content = event.features[0].properties.content let content = event.features[0].properties.content
let title = event.features[0].properties.title let title = event.features[0].properties.title
let url = event.features[0].properties.attachment let url = event.features[0].properties.attachment
let author = event.features[0].properties.author let author = event.features[0].properties.author
let category = event.features[0].properties.category let category = event.features[0].properties.category
let date = event.features[0].properties.date let date = event.features[0].properties.date
console.log(event.features[0].properties) //console.log(event.features[0].properties)
let info = "<h2>"+title+"</h2><h3>"+author+"</h3><p>"+date+"</p>"+content+"<br/><audio class=\"marker-player\"controls autoplay src=\""+url+"\"></audio>" let info = "<h2>"+title+"</h2><h3>"+author+"</h3><p>"+date+"</p>"+content+"<br/><audio class=\"marker-player\"controls autoplay src=\""+url+"\"></audio>"
console.log(event.features[0]); //console.log(event.features[0]);
this.appService.clear() this.appService.clear()
this.appService.add(info) this.appService.add(info)
@ -93,7 +128,7 @@ export class MapBoxComponent implements OnInit {
el.className = 'marker active-marker'; el.className = 'marker active-marker';
this.activeMarker = new mapboxgl.Marker(el) this.activeMarker = new mapboxgl.Marker(el)
.setLngLat(event.features[0].geometry.coordinates) .setLngLat(event.features[0].geometry.coordinates)
.addTo(this.map); .addTo(this.map);
}) })
this.map.on('mouseenter',"clusters", (event) => { this.map.on('mouseenter',"clusters", (event) => {
@ -106,7 +141,7 @@ export class MapBoxComponent implements OnInit {
this.map.setFeatureState({source:'soinumapa',id: id}, { hover:true }) this.map.setFeatureState({source:'soinumapa',id: id}, { hover:true })
this.hoverid = id this.hoverid = id
}) })
this.map.on("mouseleave", "clusters", () => { this.map.on("mouseleave", "clusters", () => {
this.map.getCanvas().style.cursor = ''; this.map.getCanvas().style.cursor = '';
}); });
@ -118,60 +153,47 @@ export class MapBoxComponent implements OnInit {
}); });
this.map.on('load',(event) => { this.map.on('load',(event) => {
this.map.addSource('soinumapa', {
let feed = "http://www.soinumapa.net/geojson/" type: 'geojson',
data: '/assets/soinumapa.geojson',
this.map.addSource('soinumapa', { cluster: true,
type: 'geojson', clusterMaxZoom: 30,
//data: feed, clusterRadius: 50,
data: '/assets/soinumapa.geojson', })
cluster:true,
clusterMaxZoom: 30,
clusterRadius: 50
})
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.addLayer({ this.map.addLayer({
id: "clusters", id: "clusters",
type: "circle", type: "circle",
source: "soinumapa", source: "soinumapa",
filter: ["has", "point_count"], filter: ["has", "point_count"],
paint: { paint: {
// Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
"circle-color": [ "circle-color": [
"step", "step",
["get", "point_count"], ["get", "point_count"],
"#ff6968", "#e5c126",
100, 5,
"#efeec2", "#e5c53c",
750, 10,
"#f28cb1" "#f46a40"
], ],
"circle-blur": 0.3,
"circle-radius": [ "circle-radius": [
"step", "step",
["get", "point_count"], ["get", "point_count"],
20, 20,
100, 3,
30, 30,
5,
40,
7,
50,
10,
60,
750, 750,
40 80
] ]
} }
}); });
this.map.addLayer({ this.map.addLayer({
id: "cluster-count", id: "cluster-count",
type: "symbol", type: "symbol",
@ -183,11 +205,9 @@ export class MapBoxComponent implements OnInit {
"text-size": 12 "text-size": 12
} }
}); });
this.map.loadImage('/assets/icon-red.png', (error,image) => { this.map.loadImage('/assets/icon-red.png', (error,image) => {
if (error) throw error; if (error) throw error;
this.map.addImage('icon-red',image); this.map.addImage('icon-red',image);
this.map.addLayer({ this.map.addLayer({
id: "soinumapa", id: "soinumapa",
source: "soinumapa", source: "soinumapa",
@ -204,10 +224,9 @@ export class MapBoxComponent implements OnInit {
1 1
] ]
} }
}) })
}) //load image }) //load image
//}) // load feed
}) })
} }

View File

@ -0,0 +1,233 @@
import { Component, OnInit } from '@angular/core';
import * as mapboxgl from 'mapbox-gl';
import { MapService } from '../map.service';
import { AppService } from '../app.service';
import { GeoJson, FeatureCollection} from '../map';
@Component({
selector: 'map-box',
templateUrl: './map-box.component.html',
styleUrls: ['./map-box.component.css']
})
export class MapBoxComponent implements OnInit {
map: mapboxgl.Map;
style = 'mapbox://styles/mapbox/outdoors-v9';
lng = -2.047919;
lat = 42.383986;
message = 'Map from Sartaguda';
// data
source: any;
markers: any;
hoverid: null;
activeMarker: any;
constructor(
private mapService: MapService,
public appService: AppService
) { }
ngOnInit() {
this.initializeMap()
}
private initializeMap() {
this.markers = this.mapService.getMarkers()
this.buildMap()
}
buildMap() {
console.log("building map")
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/outdoors-v9',
//style: 'mapbox://styles/lrullo/cjm4bqlj2b36y2ss4mpq41uxs',
zoom: 13,
pitch: 60, // pitch in degrees
bearing: 0, // bearing in degrees
center: [this.lng, this.lat],
});
// controls
this.map.addControl(new mapboxgl.NavigationControl())
this.map.on('click','clusters', (event) => {
let features = this.map.queryRenderedFeatures(event.point, { layers: ['clusters'] });
let clusterId = features[0].properties.cluster_id;
this.map.getSource('soinumapa').getClusterExpansionZoom(clusterId, (err,zoom) => {
if (err) return
this.map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
})
})
this.map.on('click','soinumapa', (event) => {
// clean old markers
//let m = document.getElementsByClassName('active-marker')
//if (m.length > 0) document.removeChild(m[0])
if (this.activeMarker!=undefined) this.activeMarker.remove()
const coordinates = [event.lngLat.lng, event.lngLat.lat]
const newMarker = new GeoJson(coordinates, { message : 'new marker' })
let content = event.features[0].properties.content
let title = event.features[0].properties.title
let url = event.features[0].properties.attachment
let author = event.features[0].properties.author
let category = event.features[0].properties.category
let date = event.features[0].properties.date
console.log(event.features[0].properties)
let info = "<h2>"+title+"</h2><h3>"+author+"</h3><p>"+date+"</p>"+content+"<br/><audio class=\"marker-player\"controls autoplay src=\""+url+"\"></audio>"
console.log(event.features[0]);
this.appService.clear()
this.appService.add(info)
var el = document.createElement('div');
el.className = 'marker active-marker';
this.activeMarker = new mapboxgl.Marker(el)
.setLngLat(event.features[0].geometry.coordinates)
.addTo(this.map);
})
this.map.on('mouseenter',"clusters", (event) => {
this.map.getCanvas().style.cursor = 'pointer';
});
this.map.on('mouseenter','soinumapa', (event) => {
this.map.getCanvas().style.cursor = 'pointer';
let id = event.features[0].properties.id
this.map.setFeatureState({source:'soinumapa',id: id}, { hover:true })
this.hoverid = id
})
this.map.on("mouseleave", "clusters", () => {
this.map.getCanvas().style.cursor = '';
});
this.map.on("mouseleave", "soinumapa", () => {
this.map.getCanvas().style.cursor = '';
if (this.hoverid) this.map.setFeatureState({source: 'soinumapa', id: this.hoverid}, { hover: false});
this.hoverid = null
});
this.map.on('load',(event) => {
console.log("map is loadded")
console.log(this.map)
/* test */
var em = document.createElement('div');
em.className = 'marker ecouterlemonde';
this.activeMarker = new mapboxgl.Marker(em)
.setLngLat([2.349014,48.864716])
.addTo(this.map);
let feed = "http://www.soinumapa.net/geojson/"
this.map.addSource('soinumapa', {
type: 'geojson',
//data: feed,
data: '/assets/soinumapa.geojson',
cluster:true,
clusterMaxZoom: 30,
clusterRadius: 50
})
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.addLayer({
id: "clusters",
type: "circle",
source: "soinumapa",
filter: ["has", "point_count"],
paint: {
"circle-color": [
"step",
["get", "point_count"],
"#ff6968",
5,
"#efeec2",
10,
"#f28cb1"
],
"circle-radius": [
"step",
["get", "point_count"],
10,
3,
20,
5,
30,
7,
40,
10,
30,
750,
40
]
}
});
this.map.addLayer({
id: "cluster-count",
type: "symbol",
source: "soinumapa",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
"text-size": 12
}
});
this.map.loadImage('/assets/icon-red.png', (error,image) => {
if (error) throw error;
this.map.addImage('icon-red',image);
this.map.addLayer({
id: "soinumapa",
source: "soinumapa",
type: "symbol",
filter: ["!", ["has", "point_count"]],
layout: {
'icon-image': "icon-red",
'icon-size': 0.5,
},
paint: {
'icon-opacity': ["case",
["boolean", ["feature-state", "hover"], false],
0.5,
1
]
}
})
}) //load image
//}) // load feed
})
}
}
/* DOCUMENTATION */
/*----
https://www.mapbox.com/help/working-with-large-geojson-data/
https://www.mapbox.com/mapbox-gl-js/example/cluster/
https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/
https://www.mapbox.com/mapbox-gl-js/example/hover-styles/
https://angularfirebase.com/lessons/build-realtime-maps-in-angular-with-mapbox-gl/
----*/

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { environment } from '../environments/environment'; import { environment } from '../environments/environment';
import { GeoJson, MARKERS } from './map';
import * as mapboxgl from 'mapbox-gl'; import * as mapboxgl from 'mapbox-gl';
import { GeoJson, MARKERS } from './map';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of'; import { of } from 'rxjs/observable/of';

View File

@ -43,24 +43,24 @@ export const MARKERS: IGeoJson[] = [
"iconSize": [5, 5] "iconSize": [5, 5]
} }
}, },
{ {
"type": "Feature", "type": "Feature",
"id" : 12351, "id" : 12351,
"geometry": { "geometry": {
"type": "Point", "type": "Point",
"coordinates": [-2.044522480456749, 42.3596491127368] "coordinates": [-2.044522480456749, 42.3596491127368]
}, },
"properties": { "properties": {
"id" : 12351, "id" : 12351,
"date" : "08/08/2018", "date" : "08/08/2018",
"category": "Mekanikoa", "category": "Mekanikoa",
"title": "Sartaguda - Traktorea", "title": "Sartaguda - Traktorea",
"author" : "Beatriz Calvo", "author" : "Beatriz Calvo",
"href" : "", "href" : "",
"content" : "Muxikak bildu eta traktorea badoa deskargatzera.<br\/><a href=\"http:\/\/www.culturanavarra.es\/eu\/landarte\">Landarte egitasmoaren laguntzarekin egindako grabaketa<\/a>.", "content" : "Muxikak bildu eta traktorea badoa deskargatzera.<br\/><a href=\"http:\/\/www.culturanavarra.es\/eu\/landarte\">Landarte egitasmoaren laguntzarekin egindako grabaketa<\/a>.",
"attachment" : "http://www.soinumapa.net/wp-content/uploads/2018/08/sartaguda_tractor.mp3", "attachment" : "http://www.soinumapa.net/wp-content/uploads/2018/08/sartaguda_tractor.mp3",
"image-url":"", "image-url":"",
"image" : "" "image" : ""
} }
}, },
{ "type": "Feature", "id" : 12330, "geometry": {"type": "Point","coordinates": [-2.038689716235922, 42.3658864254611]}, "properties": { "id" : 12330, "date" : "05/08/2018", "category": "Gizartea","title": "Sartaguda - Paraguayo bilketa", "author" : "Iñaki Martinez", "href" : "", "content" : "Uztaila iritsi bezala hasten dira Sartagudako nekazariak paraguayoak biltzen. Grabaketa honek lan horren berezko soinua erakusten du.<br\/><a href=\"http:\/\/www.culturanavarra.es\/eu\/landarte\">Landarte egitasmoaren laguntzarekin egindako grabaketa<\/a>.", "attachment" : "http://www.soinumapa.net/wp-content/uploads/2018/08/sartaguda_paraguayos.mp3","image-url":"","image" : "" } { "type": "Feature", "id" : 12330, "geometry": {"type": "Point","coordinates": [-2.038689716235922, 42.3658864254611]}, "properties": { "id" : 12330, "date" : "05/08/2018", "category": "Gizartea","title": "Sartaguda - Paraguayo bilketa", "author" : "Iñaki Martinez", "href" : "", "content" : "Uztaila iritsi bezala hasten dira Sartagudako nekazariak paraguayoak biltzen. Grabaketa honek lan horren berezko soinua erakusten du.<br\/><a href=\"http:\/\/www.culturanavarra.es\/eu\/landarte\">Landarte egitasmoaren laguntzarekin egindako grabaketa<\/a>.", "attachment" : "http://www.soinumapa.net/wp-content/uploads/2018/08/sartaguda_paraguayos.mp3","image-url":"","image" : "" }
@ -70,3 +70,20 @@ export const MARKERS: IGeoJson[] = [
] ]
export class Map {} export class Map {}
export class Documento {
constructor (
public id: number,
public coord: GeoJson,
public title: string,
public author: string,
public email: string,
public category: string,
public file: string,
public description?: string
) {}
public setCoord(coord:number[]) {
this.coord = new GeoJson(coord)
}
}

View File

@ -1,9 +1,10 @@
div.messages-container {
div.messages-container {
width:250px; width:250px;
min-width:200px; min-width:200px;
min-height:50px; min-height:50px;
max-height:80vh; max-height:80vh;
overflow-y:auto; overflow-y:auto;
background:rgba(0,0,0,0.8); background:rgba(0,0,0,0.8);
border:#fff solid 0px; border:#fff solid 0px;
margin:20px; margin:20px;
@ -12,6 +13,21 @@ div.messages-container {
font-size:0.8em; font-size:0.8em;
} }
div.messages-container::before {
display: block;
position: absolute;
top: 15px;
left: 2.7rem;
width: 0;
height: 0;
border-right: 8px solid transparent;
border-bottom: 8px solid #333;
border-left: 8px solid transparent;
content: "";
z-index: 1000;
}
h1 { font-size:1em; } h1 { font-size:1em; }
button { font-family:'Raleway',sans-serif; background:transparent; padding:5px; width:100%; color:#fff; border:#fff solid 2px;} button { font-family:'Raleway',sans-serif; background:transparent; padding:5px; width:100%; color:#fff; border:#fff solid 2px;}

View File

@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { AppService } from '../app.service'; import { AppService } from '../app.service';
@Component({ @Component({
selector: 'app-messages', selector: 'messages',
templateUrl: './messages.component.html', templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css'] styleUrls: ['./messages.component.css']
}) })

BIN
src/assets/em.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

15
src/messages.xlf Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="e953472f729d42a94847e36dca8c86f2ff37f0e8" datatype="html">
<source>El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Xabier Erkizia<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> y <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Luca Rullo<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>, de la asociación <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AUDIOLAB<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/app.component.ts</context>
<context context-type="linenumber">7</context>
</context-group>
<note priority="1" from="description">Texto intro</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -7,20 +7,47 @@ a { color:#fff; font-weight:bold; cursor:pointer; text-decoration:none;}
/* map */ /* map */
.active-marker { #map { width:100%;height:100%; position:absolute; top:0; left:0;}
width:50px;
height:50px; .active-marker {
border-radius:100%; width:50px;
border:#f95f5f solid 5px; height:50px;
border-radius:100%;
border:#000 solid 2px;
border-top:0;
animation: hideshow 3s ease infinite; animation: hideshow 3s ease infinite;
} }
.new-marker {
width:50px;
height:50px;
border-radius:100%;
border:0;
background-color:#f3e;
}
.ecouterlemonde {
width:200px;
height:200px;
background-image:url('/assets/em.jpg');
background-size:cover;
background-color:transparent;
background-position:center center;
background-repeat: no-repeat;
-webkit-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
-moz-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
}
@keyframes hideshow { @keyframes hideshow {
0% { opacity:0; transform:scale(1); } 0% { opacity:0; transform:rotate(0deg); }
50% { opacity:1; transform:scale(1.5); } 50% { opacity:1; transform:rotate(180deg); }
100% { opacity:0; transform:scale(1);} 100% { opacity:0; transform:rotate(360deg);}
} }
.marker-player { max-width:100%;margin-top:50px;} .marker-player { max-width:100%;margin-top:50px;}
/* add content */
messages { position:fixed; z-index:100; left:0; top:0;z-index:1000; }
add-content { position:absolute; right:0; top:0; z-index:1000;}