React Enlazar archivos JSON con ubicaciones geográficas
Con el mapa Ignite UI for React, puede trazar datos geográficos cargados desde varios tipos de archivos. Por ejemplo, puede cargar ubicaciones geográficas desde un archivo JSON (JavaScript Object Notation).
React Ejemplo de enlace de archivos JSON con ubicaciones geográficas
EXAMPLE
DATA
TSX
exportdefaultclassWorldUtils{
// calculate geo-paths between two locations using great circle formulapublicstatic calcPaths(origin: any, dest: any): any[] {
let interval = 200;
let paths: any[] = [[]];
let pathID = 0;
let distance = this.calcDistance(origin, dest);
if (distance <= interval) {
paths[pathID].push({ x: origin.lon, y: origin.lat });
paths[pathID].push({ x: dest.lon, y: dest.lat });
} else {
let current = origin;
let previous = origin;
for (let dist = interval; dist <= distance; dist += interval)
{
previous = current
paths[pathID].push({ x: current.lon, y: current.lat });
let bearing = this.calcBearing(current, dest);
current = this.calcDestination(current, bearing, interval);
// ensure geo-path wrap around the world through the new date-lineif (previous.lon > 150 && current.lon < -150) {
paths[pathID].push({ x: 180, y: current.lat });
paths.push([]);
pathID++
current = { lon: -180, lat: current.lat }
} elseif (previous.lon < -150 && current.lon > 150) {
paths[pathID].push({ x: -180, y: current.lat });
paths.push([]);
pathID++
current = { lon: 180, lat: current.lat }
}
}
paths[pathID].push({ x: dest.lon, y: dest.lat });
}
return paths;
}
// calculate bearing angle between two locationspublicstatic calcBearing(origin: any, dest: any): number
{
origin = this.toRadianLocation(origin);
dest = this.toRadianLocation(dest);
let range = (dest.lon - origin.lon);
let y = Math.sin(range) * Math.cos(dest.lat);
let x = Math.cos(origin.lat) * Math.sin(dest.lat) -
Math.sin(origin.lat) * Math.cos(dest.lat) * Math.cos(range);
let angle = Math.atan2(y, x);
returnthis.toDegreesNormalized(angle);
}
// calculate destination for origin location and travel distancepublicstatic calcDestination(origin: any, bearing: number, distance: number): any {
let radius = 6371.0;
origin = this.toRadianLocation(origin);
bearing = this.toRadians(bearing);
distance = distance / radius; // angular distance in radianslet lat = Math.asin(Math.sin(origin.lat) * Math.cos(distance) +
Math.cos(origin.lat) * Math.sin(distance) * Math.cos(bearing));
let x = Math.sin(bearing) * Math.sin(distance) * Math.cos(origin.lat);
let y = Math.cos(distance) - Math.sin(origin.lat) * Math.sin(origin.lat);
let lon = origin.lon + Math.atan2(x, y);
// normalize lon to coordinate between -180º and +180º
lon = (lon + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
lon = this.toDegrees(lon);
lat = this.toDegrees(lat);
return { lon: lon, lat: lat };
}
// calculate distance between two locationspublicstatic calcDistance(origin: any, dest: any): number {
origin = this.toRadianLocation(origin);
dest = this.toRadianLocation(dest);
let sinProd = Math.sin(origin.lat) * Math.sin(dest.lat);
let cosProd = Math.cos(origin.lat) * Math.cos(dest.lat);
let lonDelta = (dest.lon - origin.lon);
let angle = Math.acos(sinProd + cosProd * Math.cos(lonDelta));
let distance = angle * 6371.0;
return distance; // * 6371.0; // in km
}
publicstatic toRadianLocation(geoPoint: any): any {
let x = this.toRadians(geoPoint.lon);
let y = this.toRadians(geoPoint.lat);
return { lon: x, lat: y };
}
publicstatic toRadians(degrees: number): number
{
return degrees * Math.PI / 180;
}
publicstatic toDegrees(radians: number): number {
return (radians * 180.0 / Math.PI);
}
publicstatic toDegreesNormalized(radians: number): number
{
let degrees = this.toDegrees(radians);
degrees = (degrees + 360) % 360;
return degrees;
}
// converts latitude coordinate to a stringpublicstatic toStringLat(latitude: number): string {
let str = Math.abs(latitude).toFixed(1) + "°";
return latitude > 0 ? str + "N" : str + "S";
}
// converts longitude coordinate to a stringpublicstatic toStringLon(coordinate: number): string {
let val = Math.abs(coordinate);
let str = val < 100 ? val.toFixed(1) : val.toFixed(0);
return coordinate > 0 ? str + "°E" : str + "°W";
}
publicstatic toStringAbbr(value: number): string {
if (value > 1000000000000) {
return (value / 1000000000000).toFixed(1) + " T"
} elseif (value > 1000000000) {
return (value / 1000000000).toFixed(1) + " B"
} elseif (value > 1000000) {
return (value / 1000000).toFixed(1) + " M"
} elseif (value > 1000) {
return (value / 1000).toFixed(1) + " K"
}
return value.toFixed(0);
}
publicstatic getLongitude(location: any): number {
if (location.x) return location.x;
if (location.lon) return location.lon;
if (location.longitude) return location.longitude;
returnNumber.NaN;
}
publicstatic getLatitude(location: any): number {
if (location.y) return location.y;
if (location.lat) return location.lat;
if (location.latitude) return location.latitude;
returnNumber.NaN;
}
publicstatic getBounds(locations: any[]): any {
let minLat = 90;
let maxLat = -90;
let minLon = 180;
let maxLon = -180;
for (const location of locations) {
const crrLon = this.getLongitude(location);
if (!Number.isNaN(crrLon)) {
minLon = Math.min(minLon, crrLon);
maxLon = Math.max(maxLon, crrLon);
}
const crrLat = this.getLatitude(location);
if (!Number.isNaN(crrLat)) {
minLat = Math.min(minLat, crrLat);
maxLat = Math.max(maxLat, crrLat);
}
// if (location.x) {// minLon = Math.min(minLon, location.x);// maxLon = Math.max(maxLon, location.x);// } else if (location.lon) {// minLon = Math.min(minLon, location.lon);// maxLon = Math.max(maxLon, location.lon);// } else if (location.longitude) {// minLon = Math.min(minLon, location.longitude);// maxLon = Math.max(maxLon, location.longitude);// }// if (location.y) {// minLat = Math.min(minLat, location.y);// maxLat = Math.max(maxLat, location.y);// } else if (location.lat) {// minLat = Math.min(minLat, location.lat);// maxLat = Math.max(maxLat, location.lat);// } else if (location.latitude) {// minLat = Math.min(minLat, location.latitude);// maxLat = Math.max(maxLat, location.latitude);// }
}
const geoBounds = {
left: minLon,
top: minLat,
width: Math.abs(maxLon - minLon),
height: Math.abs(maxLat - minLat)
};
return geoBounds;
}
publicstatic getNightShapes(): any[] {
let nightShape = [];
let line: any[] = [];
for (let lon = -180; lon <= 180; lon += 1) {
// let line: any[] = [{x: lon, y: -90}, {x: lon, y: 90}];let x = lon;
let y = 75 * Math.cos(lon * Math.PI / 180);
line.push({x: x, y: y});
}
// line.push({x: 180, y: 90});// line.push({x: -180, y: 90});// line.push({x: -180, y: -90});let coordinateLine = {points: [line]};
nightShape.push(coordinateLine);
return nightShape;
}
}
ts
importReactfrom'react';
importReactDOMfrom'react-dom/client';
import'./index.css';
import WorldUtils from"./WorldUtils"import { IgrGeographicMapModule } from"@infragistics/igniteui-react-maps";
import { IgrGeographicMap } from"@infragistics/igniteui-react-maps";
import { IgrGeographicSymbolSeries } from"@infragistics/igniteui-react-maps";
import { IgrDataChartInteractivityModule } from"@infragistics/igniteui-react-charts";
import { IgrDataContext } from"@infragistics/igniteui-react-core";
import { MarkerType } from"@infragistics/igniteui-react-charts";
IgrGeographicMapModule.register();
IgrDataChartInteractivityModule.register();
exportdefaultclass MapBindingDataJsonPoints extendsReact.Component {
public geoMap: IgrGeographicMap;
constructor(props: any) {
super(props);
this.onMapRef = this.onMapRef.bind(this);
}
publicrender(): JSX.Element {
return (
<divclassName="container sample"><divclassName="container" ><IgrGeographicMapref={this.onMapRef}width="100%"height="100%"zoomable="true"/></div><divclassName="overlay-bottom-right overlay-border">Imagery Tiles: @OpenStreetMap</div></div>
);
}
public onMapRef(geoMap: IgrGeographicMap) {
if (!geoMap) { return; }
this.geoMap = geoMap;
this.geoMap.updateZoomWindow({ left: 0.2, top: 0.1, width: 0.6, height: 0.6 });
}
public componentDidMount() {
// fetching JSON data with geographic locations from public folder
fetch("https://static.infragistics.com/xplatform/data/WorldCities.json")
.then((response) => response.json())
.then(data => this.onDataLoaded(data));
}
public onDataLoaded(jsonData: any[]) {
// console.log("loaded WorldCities.json " + jsonData.length);constgeoLocations: any[] = [];
// parsing JSON data and using only cities that are capitalsfor (constjsonItemofjsonData) {
if (jsonItem.cap) {
constlocation = {
latitude: jsonItem.lat,
longitude: jsonItem.lon,
population: jsonItem.pop,
city: jsonItem.name,
country: jsonItem.country
};
geoLocations.push(location);
}
}
// creating symbol series with loaded dataconstgeoSeries = new IgrGeographicSymbolSeries( { name: "series" });
geoSeries.dataSource = geoLocations;
geoSeries.markerType = MarkerType.Circle;
geoSeries.latitudeMemberPath = "latitude";
geoSeries.longitudeMemberPath = "longitude";
geoSeries.markerBrush = "LightGray";
geoSeries.markerOutline = "Black";
geoSeries.tooltipTemplate = this.createTooltip;
// adding symbol series to the geographic ampthis.geoMap.series.add(geoSeries);
}
public createTooltip(context: any) {
constdataContext = context.dataContext as IgrDataContext;
if (!dataContext) returnnull;
constseries = dataContext.series asany;
if (!series) returnnull;
constdataItem = dataContext.item asany;
if (!dataItem) returnnull;
constpop = dataItem.population.toFixed(1) + " M";
constlat = WorldUtils.toStringLat(dataItem.latitude);
constlon = WorldUtils.toStringLon(dataItem.longitude);
return<div><divclassName="tooltipTitle" >{dataItem.city}</div><divclassName="tooltipBox"><divclassName="tooltipRow"><divclassName="tooltipLbl">Latitude:</div><divclassName="tooltipVal">{lat}</div></div><divclassName="tooltipRow"><divclassName="tooltipLbl">Longitude:</div><divclassName="tooltipVal">{lon}</div></div><divclassName="tooltipRow"><divclassName="tooltipLbl">Population</div><divclassName="tooltipVal">{pop}</div></div></div></div>
}
}
// rendering above class to the React DOMconstroot = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MapBindingDataJsonPoints/>);
tsx
¿Te gusta este ejemplo? Obtén acceso a nuestro kit de herramientas completo Ignite UI for React y comienza a crear tus propias aplicaciones en minutos. Descárgalo gratis.
El siguiente código carga y vincula IgrGeographicHighDensityScatterSeries en el componente de mapa a una matriz de objetos creados a partir de un archivo JSON cargado con ubicaciones geográficas:
import { IgrGeographicSymbolSeries } from'igniteui-react-maps';
import { MarkerType } from'igniteui-react-charts';
// ...publiccomponentDidMount() {
// fetching JSON data with geographic locations from public folder
fetch(url + "/Data/WorldCities.json")
.then((response) => response.text())
.then(data =>this.onDataLoaded(data));
}
publiconDataLoaded(jsonData: any[]) {
const geoLocations: any[] = [];
// parsing JSON data and using only cities that are capitalsfor (const jsonItem of jsonData) {
if (jsonItem.cap) {
const location = {
latitude: jsonItem.lat,
longitude: jsonItem.lon,
population: jsonItem.pop,
city: jsonItem.name,
country: jsonItem.country
};
geoLocations.push(location);
}
}
// creating symbol series with loaded dataconst geoSeries = new IgrGeographicSymbolSeries( { name: "series" });
geoSeries.dataSource = geoLocations;
geoSeries.markerType = MarkerType.Circle;
geoSeries.latitudeMemberPath = "latitude";
geoSeries.longitudeMemberPath = "longitude";
geoSeries.markerBrush = "LightGray";
geoSeries.markerOutline = "Black";
// adding symbol series to the geographic ampthis.geoMap.series.add(geoSeries);
}
ts