#LasCallesDeEncarnación
@jsenag
github.com/jessisena
Ingeniera informática Posgraduada UX
Para conseguirlo:
Crear un mapa mundial.
Representar las calles con nombres de mujer y de hombre.
Enlazar cada calle de mujer con su artículo en Wikipedia
Identificar quiénes no tienen entrada
2. Tratamiento de datos
3. Generar el visor
1. Extracción de datos
OBJETIVO:
Obtener fichero con SÓLO las CALLES de una ciudad
Herramientas:
Tile Calculator - OSM QA Tiles - TileReduce
Implementa MapReduce
(computación paralela)
Análisis geoespacial distribuido
JavaScript + Mbtiles
Gestión de Tiles Gestión resultados parciales y final
"MapReduce" versión "GEO"
reduce.js
Ejecución de operaciones y análisis
map.js
Tile
resultado
Definir BBOX y path a MBTILES
reduce.js
const opts = {
bbox: [-84.12, 9.9, -84.02, 9.96],
log: true,
zoom: 12,
sources: [
{
name: 'osm',
mbtiles: path.join(__dirname, 'data/latest.planet.mbtiles')
}
],
maxWorkers: 4,
map: __dirname+'/map.js'
};
.on('reduce', function(result, tile){
num++;
finalGeojson.features = finalGeojson.features.concat(result.features) ;
})
.on('end', function(error){
(...)
});
Generar Geojson final solo con calles
module.exports = function(tileLayers, tile, writeData, done){
const osmRoads = cleanGeoms(normalize(flatten(clip(tileLayers.osm.osm, tile))));
done(null, osmRoads);
};
PASO 1: Clip + flatten + normalize
Turf.js
+
@mapbox/Tilebelt
map.js
geojson-flatten
+
geojson-normalize
PASO 2: CleanGeoms
LineString MultiLineString
Polygon
module.exports = function(tileLayers, tile, writeData, done){
const osmRoads = cleanGeoms(normalize(flatten(clip(tileLayers.osm.osm, tile))));
done(null, osmRoads);
};
map.js
PASO 2: CleanGeoms
Polygon
module.exports = function(tileLayers, tile, writeData, done){
const osmRoads = cleanGeoms(normalize(flatten(clip(tileLayers.osm.osm, tile))));
done(null, osmRoads);
};
map.js
FIXED!
function isValidSquare(geom) {
return (
geom.geometry.type === 'Polygon' &&
geom.properties.highway &&
geom.properties.highway === 'pedestrian'&&
geom.properties.area &&
geom.properties.area === 'yes'
&& geom.properties.name !== undefined
);
}
PASO 2: CleanGeoms
module.exports = function(tileLayers, tile, writeData, done){
var osmRoads = cleanGeoms(normalize(flatten(clip(tileLayers.osm.osm, tile))));
done(null, osmRoads);
};
map.js
PASO 2: CleanGeoms
geom.properties = {
name: geom.properties.name,
id: geom.properties['@id'],
wikipedia_link: '',
gender: 'unknown',
scale: ''
};
module.exports = function(tileLayers, tile, writeData, done){
var osmRoads = cleanGeoms(normalize(flatten(clip(tileLayers.osm.osm, tile))));
done(null, osmRoads);
};
map.js
Nombre "limpio" para clasificación
const filterList = ['Paseo','Río', 'Avenida', 'Hacienda', 'Puerto', 'Callejón', 'Calle', 'Calzada', 'Camino', 'Av.','Paso', 'Cañada', 'Minas', 'Cerrada',
'Puebla', 'Principal', 'Central','Primera', 'Segunda', 'Portón', 'Lateral', 'Calz.', 'Corrido', 'Casa', 'Villa', 'Mejía',
'Vía', 'Via', 'Real', 'Isla', 'Avendida', 'Marisma', 'Rada', 'Raudal', 'Ribera', 'Embocadura', 'Cataratas', 'Médanos',
'Mirador', 'Av', 'Jardín', 'A.', 'Circuito','Gral.', 'Rincón', 'Calz', 'Rinconada', 'Periférico', 'Cda', 'Jardin',
'C.', 'Callejon', 'Colegio', 'Valle', 'avenida', 'camino', 'calle', 'Calle', 'Rotonda', 'Parqueo', 'Parque', 'entrada',
'Entrada', 'sendero', 'Sendero', 'Pasaje', 'pasaje', 'Puerto', 'Ciudad', 'Puente', 'Boulevard', 'Agrosuperior', 'Bodegas',
'Autobanco', 'SkyTrace', 'Plaza', 'Motel', 'C/', 'Rotonda', 'Drive', 'Residencial', 'Automac',
'Auto', 'Transcersal', 'Inter', 'Pasillo', 'Centro', 'Caminito', 'Arandas', 'Proveedores', 'Cajero', 'Zona', 'Primer', 'Res.'
];
prefijos de tipos calles
idiomas!
RESULTADO FINAL:
OBJETIVOS:
SOLUCIÓN 1:
Limitaciones de uso
Lento (petición/nombre)
Parseo "Nombre + Apellido"
API
SOLUCIÓN 2:
Listado CSV (fuente INE)
+25.000 nombres clasificados
Diccionario local
github.com/marcboquet/spanish-names
Cargar en memoria diccionarios
Coger nombre "limpio de CSV"
Jacint (Verdaguer)
Aparece en diccionario nombres mujer?
Aparece en diccionario nombres hombre?
NO
SI
es MUJER
SI
es HOMBRE
NO
Descartamos calle
new Set();
SOLUCIÓN 1:
Lenta (petición/calle)
Parseo resultado complejo
API de MediaWiki
SOLUCIÓN 2:
Wikidata Wikiquote Wikinoticas Wikisource
68.000 entradas
SOLUCIÓN 2:
68.000 entradas
https://fusejs.io/
Las calles son de persona
Clasificación F/M
Enlaces a Wikipedia
nombreciudad_streets.geojson
¿Cómo?
Generar
GEOSJON FINAL
Generar
GEOSJON FINAL
const streeMap = new Map();
(...)
streeMap.set(splitLine[0], {
url: url,
gender: splitLine[4],
scale: ""
});
var finalGeojson = {
"type": "FeatureCollection",
"features": []
};
for (var key in geojson.features) {
if(streeMap.has(geojson.features[key].properties.name)){
(...)
finalGeojson.features.push(geojson.features[key]);
}
}
Generar
ESTADÍSTICAS
if(!tratadosList.has(geojson.features[key].properties.name)){
tratadosList.add(geojson.features[key].properties.name);
if (objValues.url !== ('' && null && undefined) && objValues.gender.toLowerCase() === FEMALE){
stats.numLink++;
stats.numFemale++;
}else if (objValues.gender.toLowerCase() === FEMALE){
stats.numFemale++;
stats.numNoLink++;
noLinkList += `\n${geojson.features[key].properties.name}`;
}else{
stats.numMale++;
}
}
Problemas/errores conocidos.
map.addLayer({
"id": `${sourcename}`,
"type": "line",
"source": {
"type": "geojson",
"data": geojson
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-blur": ['case', ['==', ['get', 'wikipedia_link'], ''], 4, 1],
'line-color': ['case', ['==', ['get', 'gender'], 'Female'], '#ffca3a', '#00B99E'],
"line-width": ['case', ['==', ['get', 'gender'], 'Female'], widthFemale, widthMale],
}
});
GeoJSON
VectorTiles?
github.com/geochicasosm/
Intrucciones en README.md
https://geochicasosm.github.io/lascallesdelasmujeres/ https://github.com/geochicasosm
@geochicasosm
www.geochicas.org
Jessica Sena - @jsenag