You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
8.7 KiB
243 lines
8.7 KiB
/* Draw GeoJSON |
|
|
|
Iterates through the latitude and longitude values, converts the values to XYZ coordinates, |
|
and draws the geoJSON geometries. |
|
|
|
*/ |
|
|
|
var x_values = []; |
|
var y_values = []; |
|
var z_values = []; |
|
|
|
function drawThreeGeo(json, radius, shape, options) { |
|
|
|
var json_geom = createGeometryArray(json); |
|
//An array to hold the feature geometries. |
|
var convertCoordinates = getConversionFunctionName(shape); |
|
//Whether you want to convert to spherical or planar coordinates. |
|
var coordinate_array = []; |
|
//Re-usable array to hold coordinate values. This is necessary so that you can add |
|
//interpolated coordinates. Otherwise, lines go through the sphere instead of wrapping around. |
|
|
|
for (var geom_num = 0; geom_num < json_geom.length; geom_num++) { |
|
|
|
if (json_geom[geom_num].type == 'Point') { |
|
convertCoordinates(json_geom[geom_num].coordinates, radius); |
|
drawParticle(y_values[0], z_values[0], x_values[0], options); |
|
|
|
} else if (json_geom[geom_num].type == 'MultiPoint') { |
|
for (var point_num = 0; point_num < json_geom[geom_num].coordinates.length; point_num++) { |
|
convertCoordinates(json_geom[geom_num].coordinates[point_num], radius); |
|
drawParticle(y_values[0], z_values[0], x_values[0], options); |
|
} |
|
|
|
} else if (json_geom[geom_num].type == 'LineString') { |
|
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates); |
|
|
|
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { |
|
convertCoordinates(coordinate_array[point_num], radius); |
|
} |
|
drawLine(y_values, z_values, x_values, options); |
|
|
|
} else if (json_geom[geom_num].type == 'Polygon') { |
|
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates.length; segment_num++) { |
|
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[segment_num]); |
|
|
|
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { |
|
convertCoordinates(coordinate_array[point_num], radius); |
|
} |
|
drawLine(y_values, z_values, x_values, options); |
|
} |
|
|
|
} else if (json_geom[geom_num].type == 'MultiLineString') { |
|
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates.length; segment_num++) { |
|
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[segment_num]); |
|
|
|
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { |
|
convertCoordinates(coordinate_array[point_num], radius); |
|
} |
|
drawLine(y_values, z_values, x_values, options); |
|
} |
|
|
|
} else if (json_geom[geom_num].type == 'MultiPolygon') { |
|
for (var polygon_num = 0; polygon_num < json_geom[geom_num].coordinates.length; polygon_num++) { |
|
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates[polygon_num].length; segment_num++) { |
|
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[polygon_num][segment_num]); |
|
|
|
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { |
|
convertCoordinates(coordinate_array[point_num], radius); |
|
} |
|
drawLine(y_values, z_values, x_values, options); |
|
} |
|
} |
|
} else { |
|
throw new Error('The geoJSON is not valid.'); |
|
} |
|
} |
|
} |
|
|
|
function createGeometryArray(json) { |
|
var geometry_array = []; |
|
|
|
if (json.type == 'Feature') { |
|
geometry_array.push(json.geometry); |
|
} else if (json.type == 'FeatureCollection') { |
|
for (var feature_num = 0; feature_num < json.features.length; feature_num++) { |
|
geometry_array.push(json.features[feature_num].geometry); |
|
} |
|
} else if (json.type == 'GeometryCollection') { |
|
for (var geom_num = 0; geom_num < json.geometries.length; geom_num++) { |
|
geometry_array.push(json.geometries[geom_num]); |
|
} |
|
} else { |
|
throw new Error('The geoJSON is not valid.'); |
|
} |
|
//alert(geometry_array.length); |
|
return geometry_array; |
|
} |
|
|
|
function getConversionFunctionName(shape) { |
|
var conversionFunctionName; |
|
|
|
if (shape == 'sphere') { |
|
conversionFunctionName = convertToSphereCoords; |
|
} else if (shape == 'plane') { |
|
conversionFunctionName = convertToPlaneCoords; |
|
} else { |
|
throw new Error('The shape that you specified is not valid.'); |
|
} |
|
return conversionFunctionName; |
|
} |
|
|
|
function createCoordinateArray(feature) { |
|
//Loop through the coordinates and figure out if the points need interpolation. |
|
var temp_array = []; |
|
var interpolation_array = []; |
|
|
|
for (var point_num = 0; point_num < feature.length; point_num++) { |
|
var point1 = feature[point_num]; |
|
var point2 = feature[point_num - 1]; |
|
|
|
if (point_num > 0) { |
|
if (needsInterpolation(point2, point1)) { |
|
interpolation_array = [point2, point1]; |
|
interpolation_array = interpolatePoints(interpolation_array); |
|
|
|
for (var inter_point_num = 0; inter_point_num < interpolation_array.length; inter_point_num++) { |
|
temp_array.push(interpolation_array[inter_point_num]); |
|
} |
|
} else { |
|
temp_array.push(point1); |
|
} |
|
} else { |
|
temp_array.push(point1); |
|
} |
|
} |
|
return temp_array; |
|
} |
|
|
|
function needsInterpolation(point2, point1) { |
|
//If the distance between two latitude and longitude values is |
|
//greater than five degrees, return true. |
|
var lon1 = point1[0]; |
|
var lat1 = point1[1]; |
|
var lon2 = point2[0]; |
|
var lat2 = point2[1]; |
|
var lon_distance = Math.abs(lon1 - lon2); |
|
var lat_distance = Math.abs(lat1 - lat2); |
|
|
|
if (lon_distance > 5 || lat_distance > 5) { |
|
return true; |
|
} else { |
|
return false; |
|
} |
|
} |
|
|
|
function interpolatePoints(interpolation_array) { |
|
//This function is recursive. It will continue to add midpoints to the |
|
//interpolation array until needsInterpolation() returns false. |
|
var temp_array = []; |
|
var point1, point2; |
|
|
|
for (var point_num = 0; point_num < interpolation_array.length - 1; point_num++) { |
|
point1 = interpolation_array[point_num]; |
|
point2 = interpolation_array[point_num + 1]; |
|
|
|
if (needsInterpolation(point2, point1)) { |
|
temp_array.push(point1); |
|
temp_array.push(getMidpoint(point1, point2)); |
|
} else { |
|
temp_array.push(point1); |
|
} |
|
} |
|
|
|
temp_array.push(interpolation_array[interpolation_array.length - 1]); |
|
|
|
if (temp_array.length > interpolation_array.length) { |
|
temp_array = interpolatePoints(temp_array); |
|
} else { |
|
return temp_array; |
|
} |
|
return temp_array; |
|
} |
|
|
|
function getMidpoint(point1, point2) { |
|
var midpoint_lon = (point1[0] + point2[0]) / 2; |
|
var midpoint_lat = (point1[1] + point2[1]) / 2; |
|
var midpoint = [midpoint_lon, midpoint_lat]; |
|
|
|
return midpoint; |
|
} |
|
|
|
function convertToSphereCoords(coordinates_array, sphere_radius) { |
|
var lon = coordinates_array[0]; |
|
var lat = coordinates_array[1]; |
|
|
|
x_values.push(Math.cos(lat * Math.PI / 180) * Math.cos(lon * Math.PI / 180) * sphere_radius); |
|
y_values.push(Math.cos(lat * Math.PI / 180) * Math.sin(lon * Math.PI / 180) * sphere_radius); |
|
z_values.push(Math.sin(lat * Math.PI / 180) * sphere_radius); |
|
} |
|
|
|
function convertToPlaneCoords(coordinates_array, radius) { |
|
var lon = coordinates_array[0]; |
|
var lat = coordinates_array[1]; |
|
|
|
z_values.push((lat / 180) * radius); |
|
y_values.push((lon / 180) * radius); |
|
} |
|
|
|
function drawParticle(x, y, z, options) { |
|
var particle_geom = new THREE.Geometry(); |
|
particle_geom.vertices.push(new THREE.Vector3(x, y, z)); |
|
|
|
var particle_material = new THREE.ParticleSystemMaterial(options); |
|
|
|
var particle = new THREE.ParticleSystem(particle_geom, particle_material); |
|
scene.add(particle); |
|
|
|
clearArrays(); |
|
} |
|
|
|
function drawLine(x_values, y_values, z_values, options) { |
|
var line_geom = new THREE.Geometry(); |
|
createVertexForEachPoint(line_geom, x_values, y_values, z_values); |
|
|
|
var line_material = new THREE.LineBasicMaterial(options); |
|
var line = new THREE.Line(line_geom, line_material); |
|
scene.add(line); |
|
|
|
clearArrays(); |
|
} |
|
|
|
function createVertexForEachPoint(object_geometry, values_axis1, values_axis2, values_axis3) { |
|
for (var i = 0; i < values_axis1.length; i++) { |
|
object_geometry.vertices.push(new THREE.Vector3(values_axis1[i], |
|
values_axis2[i], values_axis3[i])); |
|
} |
|
} |
|
|
|
function clearArrays() { |
|
x_values.length = 0; |
|
y_values.length = 0; |
|
z_values.length = 0; |
|
}
|
|
|