Last active
June 20, 2016 01:48
-
-
Save codemasher/713e2505bbd517e4530bc59a48b5cb60 to your computer and use it in GitHub Desktop.
convert a https://api.guildwars2.com/v2/continents response to GeoJSON - see https://github.com/arenanet/api-cdi/pull/62
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Smiley on 19.06.2016. | |
*/ | |
/** | |
* Class GW2GeoJSON | |
*/ | |
class GW2GeoJSON{ | |
/** | |
* GW2GeoJSON constructor | |
* | |
* @param data | |
*/ | |
constructor(data){ | |
this.data = data; | |
this.featureCollections = {}; | |
this.viewRect = [[0, 0], [32768, 32768]]; | |
// todo | |
this.layers = [ | |
'region_label', 'region_poly', | |
'map_label', 'map_poly', | |
'sector_label', 'sector_poly', | |
'task_label', // 'task_poly', | |
'heropoint_icon', | |
'waypoint_icon', | |
'landmark_icon', | |
'vista_icon', | |
'unlock_icon', | |
// 'camp', 'tower', 'keep', 'castle', 'ruins', 'generic', 'resource' | |
]; | |
this.layers.forEach(layer => this.featureCollections[layer] = new GeoJSONFeatureCollection()); | |
} | |
/** | |
* @returns {*} | |
*/ | |
getData(){ | |
// todo: workaround https://gitter.im/arenanet/api-cdi?at=5754480da30177644b9982b7 | |
if(this.data.id === 3 && typeof this.data.regions[7] === 'object'){ | |
this.viewRect = [[5118, 6922], [16382, 16382]]; | |
} | |
else if(this.data.continent_rect){ | |
this.viewRect = this.data.continent_rect; | |
} | |
else if(this.data.clamped_view){ | |
this.viewRect = this.data.clamped_view; | |
} | |
else if(this.data.texture_dims){ | |
this.viewRect = [[0, 0], json.texture_dims]; | |
} | |
// a response to floors | |
if(this.data.regions){ | |
Object.keys(this.data.regions).forEach(regionID => this.region(this.data.regions[regionID])); | |
} | |
// a regions response | |
else if(this.data.maps){ | |
this.region(this.data); | |
} | |
// an actual map response | |
else if(this.data.points_of_interest){ | |
this.map(this.data); | |
} | |
Object.keys(this.featureCollections).forEach((f) => this.featureCollections[f] = this.featureCollections[f].getJSON()); | |
return { | |
viewRect: this.viewRect, | |
featureCollections: this.featureCollections, | |
}; | |
} | |
/** | |
* @param region | |
*/ | |
region(region){ | |
// console.log('region', region); | |
// todo @Lawton: region.id plz? PR... ikr. | |
this.featureCollections.region_label.addFeature({ | |
name : region.name, | |
type : 'region', | |
layertype: 'label', | |
}).setGeometry(region.label_coord); | |
this.featureCollections.region_poly.addFeature({ | |
name : region.name, | |
type : 'region', | |
layertype: 'poly', | |
}).setGeometry(new GW2ContinentRect(region.continent_rect).getPoly(), 'Polygon'); | |
// loop through the maps | |
Object.keys(region.maps).forEach(mapID => this.map(region.maps[mapID])); | |
} | |
/** | |
* @param map | |
*/ | |
map(map){ | |
// console.log('map', map); | |
// map label | |
var rect = new GW2ContinentRect(map.continent_rect); | |
this.featureCollections.map_label.addFeature({ | |
name : map.name, | |
default_floor : map.default_floor, | |
min_level : map.min_level, | |
max_level : map.max_level, | |
type : 'map', | |
layertype : 'label', | |
// todo @Lawton: map.label_coord? | |
}).setGeometry(rect.getCenter()).setID(map.id); | |
// map bounds | |
this.featureCollections.map_poly.addFeature({ | |
name : map.name, | |
type : 'map', | |
layertype: 'poly', | |
}).setGeometry(rect.getPoly(), 'Polygon').setID(map.id); | |
// sectors | |
Object.keys(map.sectors).forEach(sectorId =>{ | |
var sector = map.sectors[sectorId]; | |
// console.log('sector', sector); | |
// label | |
this.featureCollections.sector_label.addFeature({ | |
name : sector.name, | |
chat_link: sector.chat_link, | |
level : sector.level, | |
type : 'sector', | |
layertype: 'label', | |
}).setGeometry(sector.coord).setID(sector.id); | |
// bounds | |
this.featureCollections.sector_poly.addFeature({ | |
name : sector.name, | |
type : 'sector', | |
layertype: 'poly', | |
}).setGeometry([sector.bounds], 'Polygon').setID(sector.id); | |
}); | |
// POI | |
Object.keys(map.points_of_interest).forEach(poiID =>{ | |
var poi = map.points_of_interest[poiID]; | |
// console.log(poi); | |
this.featureCollections[poi.type + '_icon'].addFeature({ | |
name : poi.name || '', | |
type : poi.type, | |
chat_link: poi.chat_link || false, | |
layertype: 'icon', | |
icon : { | |
landmark: 'https://render.guildwars2.com/file/25B230711176AB5728E86F5FC5F0BFAE48B32F6E/97461.png', | |
unlock : 'https://render.guildwars2.com/file/943538394A94A491C8632FBEF6203C2013443555/102478.png', // dungeon icon | |
vista : 'https://render.guildwars2.com/file/A2C16AF497BA3A0903A0499FFBAF531477566F10/358415.png', | |
waypoint: 'https://render.guildwars2.com/file/32633AF8ADEA696A1EF56D3AE32D617B10D3AC57/157353.png', | |
}[poi.type], | |
}).setGeometry(poi.coord).setID(poi.id || false); | |
}); | |
// tasks | |
Object.keys(map.tasks).forEach(taskID =>{ | |
var task = map.tasks[taskID]; | |
// console.log(task); | |
// label | |
this.featureCollections.task_label.addFeature({ | |
name : task.objective, | |
chat_link: task.chat_link, | |
level : task.level, | |
type : 'task', | |
layertype: 'icon', | |
icon : 'https://render.guildwars2.com/file/09ACBA53B7412CC3C76E7FEF39929843C20CB0E4/102440.png', | |
}).setGeometry(task.coord).setID(task.id); | |
/* | |
// todo: https://gitter.im/arenanet/api-cdi?at=57585f2ea1be01c01a78094f | |
this.featureCollections.task_poly.addFeature({ | |
name : task.objective, | |
type : 'task', | |
layertype: 'poly', | |
}).setGeometry(task.bounds, 'Polygon').setID(task.id); | |
*/ | |
}); | |
// heropoints (skill_challenges) | |
// todo: https://github.com/arenanet/api-cdi/issues/329 | |
map.skill_challenges.forEach(heropoint =>{ | |
this.featureCollections.heropoint_icon.addFeature({ | |
name : '', | |
coords : heropoint.coord, | |
type : 'heropoint', | |
layertype: 'icon', | |
icon : 'https://render.guildwars2.com/file/B4EC6BB3FDBC42557C3CAE0CAA9E57EBF9E462E3/156626.png', | |
}).setGeometry(heropoint.coord); | |
}); | |
} | |
} | |
/** | |
* Class GW2ContinentRect | |
*/ | |
class GW2ContinentRect{ | |
/** | |
* GW2ContinentRect constructor | |
* | |
* @param continent_rect | |
*/ | |
constructor(continent_rect){ | |
this.rect = continent_rect; | |
} | |
/** | |
* returns bounds for L.LatLngBounds() | |
* | |
* @returns {*[]} | |
*/ | |
getBounds(){ | |
return [ | |
[this.rect[0][0], this.rect[1][1]], | |
[this.rect[1][0], this.rect[0][1]] | |
] | |
} | |
/** | |
* returns the center of the rectangle | |
* | |
* @returns {*[]} | |
*/ | |
getCenter(){ | |
return [ | |
(this.rect[0][0] + this.rect[1][0]) / 2, | |
(this.rect[0][1] + this.rect[1][1]) / 2 | |
] | |
} | |
/** | |
* returns a polygon made of the rectangles corners | |
* | |
* @returns {*[]} | |
*/ | |
getPoly(){ | |
return [[ | |
[this.rect[0][0], this.rect[0][1]], | |
[this.rect[1][0], this.rect[0][1]], | |
[this.rect[1][0], this.rect[1][1]], | |
[this.rect[0][0], this.rect[1][1]] | |
]] | |
} | |
} | |
/** | |
* Class GeoJSONFeatureCollection | |
*/ | |
class GeoJSONFeatureCollection{ | |
/** | |
* GeoJSONFeatureCollection constructor | |
*/ | |
constructor(){ | |
this.json = { | |
type: 'FeatureCollection', | |
features: [], | |
}; | |
} | |
/** | |
* @returns {{type: string, features: Array}|*} | |
*/ | |
getJSON(){ | |
this.json.features.forEach((feature, i) => this.json.features[i] = feature.getJSON()); | |
return this.json; | |
} | |
/** | |
* @param type | |
* @param properties | |
* @returns {GeoJSONFeatureCollection} | |
*/ | |
setCRS(type, properties){ | |
this.json.crs = { | |
type: type, | |
properties: properties, | |
}; | |
return this; | |
} | |
/** | |
* @param properties | |
* @returns {GeoJSONFeature} | |
*/ | |
addFeature(properties){ | |
var feature = new GeoJSONFeature(properties); | |
this.json.features.push(feature); | |
return feature; | |
} | |
} | |
/** | |
* Class GeoJSONFeature | |
*/ | |
class GeoJSONFeature{ | |
/** | |
* GeoJSONFeature constructor | |
* | |
* @param properties | |
*/ | |
constructor(properties){ | |
this.json = { | |
type: 'Feature', | |
geometry: { | |
type : '', | |
coordinates: [], | |
}, | |
properties: properties || {}, | |
}; | |
} | |
/** | |
* @returns {{type: string, geometry: {type: string, coordinates: Array}, properties: (*|{})}|*} | |
*/ | |
getJSON(){ | |
return this.json; | |
} | |
/** | |
* @param id | |
* @returns {GeoJSONFeature} | |
*/ | |
setID(id){ | |
if(id){ | |
// serving both, leaflet and Gmaps... | |
this.json.id = id; | |
this.json.properties.id = id; | |
} | |
return this; | |
} | |
/** | |
* @param coords | |
* @param type | |
* @returns {GeoJSONFeature} | |
*/ | |
setGeometry(coords, type){ | |
this.json.geometry.coordinates = coords; | |
this.json.geometry.type = GeoJSONFeature.in_array(type, [ | |
'Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon', 'GeometryCollection' | |
]) ? type : 'Point'; | |
return this; | |
} | |
/** | |
* @link http://phpjs.org/functions/in_array/ | |
* | |
* @param needle | |
* @param haystack | |
* @returns {boolean} | |
*/ | |
static in_array(needle, haystack){ | |
for(var key in haystack){ | |
if(haystack.hasOwnProperty(key)){ | |
if(haystack[key] === needle){ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment