geojson#Feature TypeScript Examples
The following examples show how to use
geojson#Feature.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
/**
* Creates Analysis result legend based on data returned from API.
*
* The equal interval method takes the maximum values minus the minimum
* and divides the result by the number of classes, which is the length
* of colors array.
*
* Finally the function calculates the upper end of each class interval
* and assigns a color.
*
* @return LegendDefinition
*/
export function createLegendFromFeatureArray(
features: Feature[],
statistic: AggregationOperations,
): LegendDefinition {
// Extract values based on aggregation operation.
const stats: number[] = features.map(f =>
f.properties && f.properties[statistic] ? f.properties[statistic] : 0,
);
const maxNum = Math.max(...stats);
const minNum = Math.min(...stats);
const colors = ['#fee5d9', '#fcae91', '#fb6a4a', '#de2d26', '#a50f15'];
const delta = (maxNum - minNum) / colors.length;
const legend: LegendDefinition = colors.map((color, index) => {
const breakpoint = Math.ceil(minNum + (index + 1) * delta);
// Make sure you don't have a value greater than maxNum.
const value = Math.min(breakpoint, maxNum);
return { value, color };
});
return legend;
}
Example #2
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
/**
* Computes the feature property value according to the scale, offset values and statistic property
*
* @return Feature
*/
export function scaleFeatureStat(
feature: Feature,
scale: number,
offset: number,
statistic: AggregationOperations,
): Feature {
const { properties } = feature;
if (!properties) {
return feature;
}
const scaledValue: number = get(properties, statistic) * scale + offset;
const scaledValueProperties = {
...properties,
[statistic]: scaledValue,
};
const scaledValueFeature: Feature = {
...feature,
properties: scaledValueProperties,
};
return scaledValueFeature;
}
Example #3
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
export async function fetchApiData(
url: string,
apiData: ApiData | AlertRequest,
): Promise<Array<KeyValueResponse | Feature>> {
return (
await fetch(url, {
method: 'POST',
cache: 'no-cache',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
// body data type must match "Content-Type" header
body: JSON.stringify(apiData),
})
)
.text()
.then(message => {
try {
return JSON.parse(message);
} catch (e) {
// In some cases the response isn't valid JSON.
// In those cases, just wrap the full response in an object.
return {
message,
};
}
});
}
Example #4
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
function mergeFeaturesByProperty(
baselineFeatures: Feature[],
aggregateData: Array<object>,
id: string,
): Feature[] {
const features = baselineFeatures.map(feature1 => {
const aggregateProperties = aggregateData.filter(
item => get(item, id) === get(feature1, ['properties', id]) && item,
);
const filteredProperties = aggregateProperties.map(filteredProperty => {
// We use geometry from response. If not, use whole admin boundary.
const filteredGeometry = get(filteredProperty, 'geometry');
const propertyItems = filteredGeometry
? omit(filteredProperty, 'geometry')
: filteredProperty;
const properties = {
...get(feature1, 'properties'),
...propertyItems,
impactValue: get(feature1, 'properties.data'),
};
const feature = filteredGeometry
? { ...feature1, geometry: filteredGeometry, properties }
: { ...feature1, properties };
return feature;
});
return filteredProperties;
});
return flatten(features);
}
Example #5
Source File: csv.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
export function parseCsv(text: string): Feature[] {
// first parse the header to guess the delimiter
// note that we do that to not rely on Papaparse logic for guessing delimiter
let delimiter
try {
const header = text.split('\n')[0]
const result = Papa.parse(header, {
header: false,
})
delimiter = result.meta.delimiter
} catch (e) {
throw new Error('CSV parsing failed: the delimiter could not be guessed')
}
const parsed = Papa.parse(text, {
header: true,
skipEmptyLines: true,
delimiter,
})
if (parsed.errors.length) {
throw new Error(
'CSV parsing failed for the following reasons:\n' +
parsed.errors
.map(
(error) =>
`* ${error.message} at row ${error.row}, column ${error.index}`
)
.join('\n')
)
}
return (parsed.data as any[]).map(jsonToGeojsonFeature)
}
Example #6
Source File: dataset-validation-page.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
loadSampleFeature() {
this.fileUploadApiService
.getSampleFeature(
this.rootId.toString(),
this.dataset.name,
this.featureIndex,
this.encoding,
viewSrs,
this.crs
)
.subscribe((feature: Feature) => (this.geoJSONData = feature))
}
Example #7
Source File: map.vector.ts From diablo2 with MIT License | 6 votes |
export function toGeoJson(c: LevelData, act: Act): GeoJSON.FeatureCollection {
const features: Feature[] = [];
for (const z of c.levels.values()) {
const mapAct = ActUtil.fromLevel(z.id);
if (mapAct !== act) continue;
const latLng = LevelBounds.sourceToLatLng(z.offset.x, z.offset.y);
features.push({
type: 'Feature',
geometry: { type: 'Point', coordinates: [latLng.lng, latLng.lat] },
properties: { name: z.name, type: 'level-name' },
});
for (const obj of z.objects) {
const feat = makeFeature(obj, z);
if (feat == null || feat === false) continue;
features.push(feat);
}
}
return toFeatureCollection(features);
}
Example #8
Source File: map.vector.ts From diablo2 with MIT License | 6 votes |
function makeFeature(obj: Diablo2LevelObject, z: Diablo2Level): GeoJSON.Feature | null | false {
if (obj.type === 'object') {
const fm = MapObjects.get(obj.id);
if (fm) return toFeature(obj, z, fm);
}
for (const filter of MapFeatureFilter) {
const fm = filter(obj);
if (fm === false) return null;
if (fm) return toFeature(obj, z, fm);
}
return null;
}
Example #9
Source File: map.vector.ts From diablo2 with MIT License | 6 votes |
function toFeature(obj: Diablo2LevelObject, z: Diablo2Level, fm: FeatureMaker): GeoJSON.Feature {
if (fm.feature === 'polygon') {
return {
type: 'Feature',
geometry: pointToPolygon(z.offset.x + obj.x, z.offset.y + obj.y, fm.width, fm.height, fm.xOffset, fm.yOffset),
properties: { ...obj, type: fm.layer, name: `${toHex(obj.id)} ${obj.name ?? ''}` },
};
}
if (fm.feature === 'point') {
const latLng = LevelBounds.sourceToLatLng(z.offset.x + obj.x, z.offset.y + obj.y);
return {
type: 'Feature',
geometry: { type: 'Point', coordinates: [latLng.lng, latLng.lat] },
properties: { ...obj, type: fm.layer, name: `${toHex(obj.id)} ${obj.name ?? ''}` },
};
}
throw new Error('Unknown feature type: ' + fm);
}
Example #10
Source File: excel.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
/**
* This will read the first sheet of the excel workbook and expect the first
* line to contain the properties names
* @param buffer
*/
export function parseExcel(buffer: ArrayBuffer): Feature[] {
const workbook = XLSX.read(buffer)
const sheet = workbook.Sheets[workbook.SheetNames[0]]
const json = XLSX.utils.sheet_to_json(sheet)
if (!json.length) {
return []
}
return json.map(jsonToGeojsonFeature)
}
Example #11
Source File: RegionLabelLayer.tsx From Teyvat.moe with GNU General Public License v3.0 | 6 votes |
_RegionLabelLayer: FunctionComponent<RegionLabelLayerProps> = ({ displayed, zoomLevel }) => {
const classes = useStyles();
const map = useMap();
const layerReference = useRef<GeoJSONLeaflet | null>(null);
useEffect(() => {
if (layerReference.current != null) {
if (displayed) {
layerReference.current.addTo(map);
} else {
layerReference.current.removeFrom(map);
}
}
}, [map, displayed]);
const pointToLayer = (featureData: Feature<Point, any>, latLng: LatLng) => {
const html = renderToString(<RegionLabel featureData={featureData} zoomLevel={zoomLevel} />);
return LeafletMarker([latLng.lng, latLng.lat], {
interactive: false, // Allow clicks to pass through.
icon: LeafletDivIcon({
html,
className: classes.regionLabelMarker,
}),
zIndexOffset: -900,
});
};
return (
<GeoJSON
ref={layerReference}
key={zoomLevel}
pointToLayer={pointToLayer}
data={RegionLabelData as GeoJsonObject}
/>
);
}
Example #12
Source File: mapSelectors.ts From react-tutorials with MIT License | 6 votes |
getMapDataFromFile = () =>
new Promise((resolve) =>
fetch('/data/world-110m.json').then((response) => {
if (response.status !== 200) {
// eslint-disable-next-line no-console
console.log(`Houston, we have a problem! ${response.status}`)
return
}
response.json().then((worldData) => {
const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
resolve(setMapObject(mapFeatures))
})
})
)
Example #13
Source File: geojson.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
/**
* This parser supports both Geojson Feature collections or arrays
* of Features
* @param text
*/
export function parseGeojson(text: string): Feature[] {
const parsed = JSON.parse(text)
const features =
parsed.type === 'FeatureCollection' ? parsed.features : parsed
if (!Array.isArray(features)) {
throw new Error(
'Could not parse GeoJSON, expected a features collection or an array of features at root level'
)
}
return features
}
Example #14
Source File: json.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
/**
* This parser only supports arrays of simple flat objects with properties
* @param text
*/
export function parseJson(text: string): Feature[] {
const parsed = JSON.parse(text)
if (!Array.isArray(parsed)) {
throw new Error('Could not parse JSON, expected an array at root level')
}
return (parsed as any[]).map(jsonToGeojsonFeature)
}
Example #15
Source File: WorldMapAtlas.tsx From react-tutorials with MIT License | 6 votes |
WorldMapAtlas = () => {
const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
useEffect(() => {
fetch('/data/world-110m.json').then((response) => {
if (response.status !== 200) {
// eslint-disable-next-line no-console
console.log(`Houston we have a problem: ${response.status}`)
return
}
response.json().then((worldData) => {
const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
setGeographies(mapFeatures)
})
})
}, [])
const projection = geoEqualEarth().scale(scale).translate([cx, cy]).rotate([0, 0])
return (
<>
<svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
<g>
{(geographies as []).map((d, i) => (
<path
key={`path-${uuid()}`}
d={geoPath().projection(projection)(d) as string}
fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
stroke="aliceblue"
strokeWidth={0.5}
/>
))}
</g>
</svg>
</>
)
}
Example #16
Source File: json.ts From geonetwork-ui with GNU General Public License v2.0 | 6 votes |
export function jsonToGeojsonFeature(object: { [key: string]: any }): Feature {
const { id, properties } = Object.keys(object)
.map((property) => (property ? property : 'unknown')) //prevent empty strings
.reduce(
(prev, curr) =>
curr.toLowerCase().endsWith('id')
? {
...prev,
id: object[curr],
}
: {
...prev,
properties: { ...prev.properties, [curr]: object[curr] },
},
{ id: undefined, properties: {} }
)
return {
type: 'Feature',
geometry: null,
properties,
...(id !== undefined && { id }),
}
}
Example #17
Source File: geospatialService.ts From react-flight-tracker with MIT License | 5 votes |
private calculatePath = (stateVectors: IStateVectorData) => {
const features: Array<Feature<Point, GeoJsonProperties>> = [];
for (var stateVector of stateVectors.states) {
// Setup last position time in ms
var lastPositionTime = this.pathPredictionCounter
// Setup altitude in m
var altitude = stateVector.geo_altitude;
if ((altitude === null) || (altitude < 0))
altitude = stateVector.baro_altitude;
if ((altitude === null) || (altitude < 0))
altitude = 0;
// Setup vertical rate
var verticalRate = stateVector.vertical_rate ? stateVector.vertical_rate : 0.0;
if (verticalRate < 0)
verticalRate *= -1;
const origin: Array<number> = [stateVector.longitude ? stateVector.longitude : 0, stateVector.latitude ? stateVector.latitude : 0]
const velocity = stateVector.velocity ? stateVector.velocity : 0;
var distance = (velocity * lastPositionTime) / 1000;
// Try to adjust the distance to the vertical rate
if (verticalRate !== 0)
distance = distance - (verticalRate * (lastPositionTime / 1000));
// Try to adjust the distance to the altitude
if (altitude > 0)
distance = (distance * earthRadius) / (earthRadius + altitude);
const bearing = stateVector.true_track ? stateVector.true_track : 0;
// Calculate the destination
const feature = destination(
origin,
distance,
bearing,
{
units: "meters"
}
);
// Adding the ICAO24 prop to the feature so that a corresponding assignment is possible later
var properties: GeoJsonProperties = {
['icao24']: stateVector.icao24
};
feature.properties = properties;
// Push the feature to the collection
features.push(feature);
}
// Increase counter time
this.pathPredictionCounter += this.pathPredictionInterval;
// Execute callbacks
Object.entries(this.pathPredictionUpdatedSubscriberDictionary).forEach(([key, value], index) => value(features))
};
Example #18
Source File: dataset-validation-page.ts From geonetwork-ui with GNU General Public License v2.0 | 5 votes |
geoJSONBBox: Feature
Example #19
Source File: RotatingRoundWorldMap.tsx From react-tutorials with MIT License | 5 votes |
WorldMap = () => {
const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
const [rotation, setRotation] = useState<number>(initRotation)
const [isRotate, setIsRotate] = useState<Boolean>(false)
useEffect(() => {
fetch('/data/world-110m.json').then((response) => {
if (response.status !== 200) {
// eslint-disable-next-line no-console
console.log(`Houston we have a problem: ${response.status}`)
return
}
response.json().then((worldData) => {
const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
setGeographies(mapFeatures)
})
})
}, [])
// geoEqualEarth
// geoOrthographic
const projection = geoOrthographic().scale(scale).translate([cx, cy]).rotate([rotation, 0])
AnimationFrame(() => {
if (isRotate) {
let newRotation = rotation
if (rotation >= 360) {
newRotation = rotation - 360
}
setRotation(newRotation + 0.2)
// console.log(`rotation: ${ rotation}`)
}
})
return (
<>
<Button
size="medium"
color="primary"
startIcon={<PlayCircleFilledWhiteIcon />}
onClick={() => {
setIsRotate(true)
}}
/>
<svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
<g>
<circle fill="#f2f2f2" cx={cx} cy={cy} r={scale} />
</g>
<g>
{(geographies as []).map((d, i) => (
<path
key={`path-${uuid()}`}
d={geoPath().projection(projection)(d) as string}
fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
stroke="aliceblue"
strokeWidth={0.5}
/>
))}
</g>
</svg>
</>
)
}
Example #20
Source File: dataset-validation-page.ts From geonetwork-ui with GNU General Public License v2.0 | 5 votes |
geoJSONData: Feature
Example #21
Source File: data-import-validation-map-panel.component.ts From geonetwork-ui with GNU General Public License v2.0 | 5 votes |
@Input() geoJson?: Feature
Example #22
Source File: analysisResultStateSlice.ts From prism-frontend with MIT License | 5 votes |
requestAndStoreExposedPopulation = createAsyncThunk<
AnalysisResult,
ExposedPopulationDispatchParams,
CreateAsyncThunkTypes
>('analysisResultState/requestAndStoreExposedPopulation', async params => {
const { exposure, date, extent, statistic, wfsLayerId } = params;
const { id, key } = exposure;
const wfsLayer = LayerDefinitions[wfsLayerId] as WMSLayerProps;
const populationLayer = LayerDefinitions[id] as WMSLayerProps;
const wfsParams: WfsRequestParams = {
url: `${wfsLayer.baseUrl}/ows`,
layer_name: wfsLayer.serverLayerName,
time: moment(date).format(DEFAULT_DATE_FORMAT),
key,
};
const apiRequest = createAPIRequestParams(
populationLayer,
extent,
date,
wfsParams,
);
const apiFeatures = (await fetchApiData(
ANALYSIS_API_URL,
apiRequest,
)) as Feature[];
const { scale, offset } = populationLayer.wcsConfig ?? {
scale: undefined,
offset: undefined,
};
const features =
!scale && !offset
? apiFeatures
: apiFeatures.map(f =>
scaleFeatureStat(f, scale || 1, offset || 0, statistic),
);
const collection: FeatureCollection = {
type: 'FeatureCollection',
features,
};
const groupBy = apiRequest.group_by;
const legend = createLegendFromFeatureArray(features, statistic);
const legendText = wfsLayer.title;
return new ExposedPopulationResult(
collection,
statistic,
legend,
legendText,
groupBy,
key,
);
})
Example #23
Source File: BoundaryDropdown.tsx From prism-frontend with MIT License | 5 votes |
GotoBoundaryDropdown = () => {
const map = useSelector(mapSelector);
const [boundaries, setBoundaries] = useState<string[]>([]);
const boundaryLayerData = useSelector(layerDataSelector(boundaryLayer.id)) as
| LayerData<BoundaryLayerProps>
| undefined;
const { data } = boundaryLayerData || {};
const {
map: { latitude, longitude, zoom },
} = appConfig;
const { t } = useSafeTranslation();
const styles = useStyles();
if (!data || !map || !enableNavigationDropdown) {
return null;
}
return (
<div className={styles.dropdownMenu}>
<CenterFocusWeak fontSize="small" className={styles.icon} />
<ButtonStyleBoundaryDropdown
selectedBoundaries={boundaries}
selectAll={false}
labelMessage={t('Go To')}
className={styles.formControl}
setSelectedBoundaries={(newSelectedBoundaries, appendMany) => {
setBoundaries(() => {
if (appendMany === true) {
return newSelectedBoundaries;
}
return newSelectedBoundaries.slice(-1);
});
if (newSelectedBoundaries.length === 0) {
map.flyTo({ center: { lng: longitude, lat: latitude }, zoom });
return;
}
const geometries = data.features
.filter(f =>
newSelectedBoundaries.includes(
f.properties && f.properties[boundaryLayer.adminCode],
),
)
.filter(f => f.geometry.type === 'MultiPolygon')
.map(f => f.geometry as MultiPolygon);
const bboxes = geometries.map(geom => {
const turfObj = multiPolygon(geom.coordinates);
const geomBbox = bbox(turfObj);
return geomBbox;
});
const bboxPolygons = bboxes.map(box => bboxPolygon(box));
const unionBbox = bboxPolygons.reduce((unionPolygon, polygon) => {
const unionObj = union(unionPolygon, polygon);
if (!unionObj) {
return unionPolygon;
}
return unionObj as Feature<Polygon>;
}, bboxPolygons[0]);
map.fitBounds(bbox(unionBbox) as Extent, {
padding: 30,
});
}}
/>
</div>
);
}
Example #24
Source File: mapObject.ts From react-tutorials with MIT License | 5 votes |
setMapObject = (data: Array<Feature<Geometry | null>>): mapObject => ({
mapFeatures: data,
})
Example #25
Source File: mapObject.ts From react-tutorials with MIT License | 5 votes |
initMapObject = (): mapObject => ({
mapFeatures: Array<Feature<null>>(),
})
Example #26
Source File: RoundWorldMap.tsx From react-tutorials with MIT License | 5 votes |
RoundWorldMap = () => {
const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
const [rotation, setRotation] = useState<number>(initRotation)
useEffect(() => {
fetch('/data/world-110m.json').then((response) => {
if (response.status !== 200) {
// eslint-disable-next-line no-console
console.log(`Houston we have a problem: ${response.status}`)
return
}
response.json().then((worldData) => {
const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
setGeographies(mapFeatures)
})
})
}, [])
const projection = geoOrthographic().scale(scale).translate([cx, cy]).rotate([rotation, 0])
return (
<svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
<g>
<circle fill="#f2f2f2" cx={cx} cy={cy} r={scale} />
</g>
<g>
{(geographies as []).map((d, i) => (
<path
key={`path-${uuid()}`}
d={geoPath().projection(projection)(d) as string}
fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
stroke="aliceblue"
strokeWidth={0.5}
/>
))}
</g>
</svg>
)
}
Example #27
Source File: AircraftLayer.tsx From react-flight-tracker with MIT License | 4 votes |
AircraftLayer: React.FC<Props> = (props) => {
// Fields
const contextName: string = 'AircraftLayer'
// External hooks
const styleTheme = useTheme();
// States
const [featureCollection, setFeatureCollection] = useState<FeatureCollection | undefined>(undefined);
const [pathPredictions, setPathPredictions] = useState<Array<Feature<Point, GeoJsonProperties>>>([]);
// Contexts
const systemContext = useContext(SystemContext)
const geospatialService = systemContext.getService<IGeospatialService>('GeospatialService');
// Refs
const pathPredictionSubscriptionRef = useRef<string>('');
// Effects
useEffect(() => {
// Mount
if (geospatialService) {
// Get a register key for the subscription and save it as reference
const registerKey = geospatialService.onPathPredictionUpdated(contextName, handlePathPredictionUpdated);
pathPredictionSubscriptionRef.current = registerKey;
}
// Unmount
return () => {
if (geospatialService) {
geospatialService.stopPathPrediction();
// Get the register key from the reference to unsubscribe
const registerKey = pathPredictionSubscriptionRef.current;
geospatialService.offPathPredictionUpdated(registerKey);
}
}
}, []);
useEffect(() => {
createFeatureCollection(pathPredictions).then((featureCollection) => {
setFeatureCollection(featureCollection);
if (!geospatialService)
return;
if (props.stateVectors.states.length > 1000) {
geospatialService.stopPathPrediction();
}
else {
geospatialService.restartPathPrediction(props.stateVectors);
}
})
}, [props.stateVectors]);
useEffect(() => {
createFeatureCollection(pathPredictions).then((featureCollection) => {
setFeatureCollection(featureCollection);
})
}, [pathPredictions]);
const handlePathPredictionUpdated = (destinations: Array<Feature<Point, GeoJsonProperties>>) => {
setPathPredictions(destinations);
};
const createFeatureCollection = (pathPredictions: Array<Feature<Point, GeoJsonProperties>>) => {
return new Promise<FeatureCollection>((res, rej) => {
var featureCollection: FeatureCollection = {
type: 'FeatureCollection',
features: []
};
for (var stateVector of props.stateVectors.states) {
if (!stateVector.latitude) {
continue;
}
if (!stateVector.longitude) {
continue;
}
// Get the index
const index = props.stateVectors.states.indexOf(stateVector);
// Check for selection
var isSelected = false;
if (props.selectedAircraft)
isSelected = stateVector.icao24 === props.selectedAircraft.icao24;
// Get callsign
const callsign = stateVector.callsign ? stateVector.callsign : stateVector.icao24;
// Get altitude
var altitude = stateVector.geo_altitude;
if ((altitude === null) || (altitude < 0))
altitude = stateVector.baro_altitude;
if ((altitude === null) || (altitude < 0))
altitude = 0;
// Get velocity in km/h
const velocity = stateVector.velocity ? (stateVector.velocity * 3.6) : -1;
// Get true track
const trueTrack = stateVector.true_track ? stateVector.true_track : 0.0;
// Get vertical rate
const verticalRate = stateVector.vertical_rate ? stateVector.vertical_rate : 0.0;
// Get is on ground
const isOnGround = stateVector.on_ground;
// Claculate color
var color = getColor(altitude);
if (isOnGround)
color = styleTheme.palette.text.secondary;
if (isSelected)
color = styleTheme.palette.primary.main;
var properties: GeoJsonProperties = {
['iconName']: getIconName(isOnGround, verticalRate, altitude, trueTrack),
['rotation']: getRotation(trueTrack, verticalRate, altitude),
['color']: color,
['isSelected']: isSelected,
['icao24']: stateVector.icao24,
['callsign']: callsign,
['altitude']: getFormattedValue(altitude, 1) + " m",
['velocity']: getFormattedValue(velocity, 1) + " km/h"
}
// Setup WGS84 coordinates
var position: Position = [stateVector.longitude, stateVector.latitude];
if (pathPredictions.length > 0) {
const feature = pathPredictions.find(feature => feature.properties !== null && feature.properties['icao24']! === stateVector.icao24);
if (feature)
position = feature.geometry.coordinates;
}
var point: Point = {
type: 'Point',
coordinates: position
};
var feature: Feature<Point, GeoJsonProperties> = {
type: 'Feature',
id: `${index}.${stateVector.icao24}`,
geometry: point,
properties: properties
}
featureCollection.features.push(feature);
}
res(featureCollection);
});
};
const getText = (): string | Expression | StyleFunction => {
var text: string | Expression | StyleFunction = '';
const simpleText = ["get", "callsign"] as Expression
const detailedText = ['format',
["get", "callsign"], { "font-scale": 1.0 },
"\n", {},
["get", "altitude"], { "font-scale": 0.75, "text-color": styleTheme.palette.text.primary },
"\n", {},
["get", "velocity"], { "font-scale": 0.75, "text-color": styleTheme.palette.text.primary }
] as StyleFunction;
if (props.zoom && props.zoom > 7)
text = simpleText;
if (props.zoom && props.zoom > 9)
text = detailedText;
return text;
};
const getSymbolLayout = () => {
var showText = false;
if (props.zoom && props.zoom > 7)
showText = true;
var isconSize = 1.0;
if (props.zoom && props.zoom > 7)
isconSize = 1.3;
if (props.zoom && props.zoom > 9)
isconSize = 1.6;
const symbolLayout: SymbolLayout = {
"icon-image": ["get", "iconName"],
"icon-allow-overlap": true,
"icon-rotate": ["get", "rotation"],
"icon-size": isconSize,
"text-field": showText ? getText() : '',
"text-optional": true,
"text-allow-overlap": true,
"text-anchor": showText ? 'top' : 'center',
"text-offset": showText ? [0, 1] : [0, 0]
};
return symbolLayout;
};
const getSymbolPaint = () => {
var symbolPaint: SymbolPaint = {
"icon-color": ["get", "color"],
"text-color": ["get", "color"],
"text-halo-width": 2,
"text-halo-color": styleTheme.palette.background.default,
"text-halo-blur": 2
};
return symbolPaint;
};
if (!props.stateVectors.states)
return null;
return (
<Source
type="geojson"
data={featureCollection}>
<Layer
id={aircraftLayerId}
type='symbol'
source='geojson'
layout={getSymbolLayout()}
paint={getSymbolPaint()} />
</Source>
)
}
Example #28
Source File: FlightMap.tsx From react-flight-tracker with MIT License | 4 votes |
FlightMap: React.FC<Props> = (props) => {
// External hooks
const styleTheme = useTheme();
// Contexts
const systemContext = useContext(SystemContext);
const getDefaultViewState = () => {
const defaultViewState: ViewState = {
latitude: Constants.DEFAULT_LATITUDE,
longitude: Constants.DEFAULT_LONGITUDE,
zoom: Constants.DEFAULT_ZOOM,
bearing: 0,
pitch: 0,
padding: {
top: 0,
bottom: 0,
left: 0,
right: 0
}
};
return defaultViewState;
};
// States
const [viewState, setViewState] = useState<ViewState>(getDefaultViewState());
// Refs
const mapRef = useRef<MapRef | null>(null);
// Effects
useEffect(() => {
// Mount
// Unmount
return () => {
}
}, []);
useEffect(() => {
const mapGeoBounds = getMapGeoBounds();
if (props.onMapChange)
props.onMapChange(viewState, mapGeoBounds);
}, [mapRef.current]);
const getMapGeoBounds = () => {
var mapGeoBounds: IMapGeoBounds = {
northernLatitude: 0.0,
easternLongitude: 0.0,
southernLatitude: 0.0,
westernLongitude: 0.0
}
if (mapRef.current) {
const map = mapRef.current.getMap();
const mapBounds = map.getBounds();
mapGeoBounds.northernLatitude = mapBounds.getNorthEast().lat;
mapGeoBounds.easternLongitude = mapBounds.getNorthEast().lng;
mapGeoBounds.southernLatitude = mapBounds.getSouthWest().lat;
mapGeoBounds.westernLongitude = mapBounds.getSouthWest().lng;
}
return mapGeoBounds;
};
const addMapSources = (map: Map) => {
svgToImageAsync(FlightIcon, 24, 24).then(image => {
if (!map.hasImage('flight-icon'))
map.addImage('flight-icon', image, { sdf: true });
});
svgToImageAsync(FlightLandIcon, 24, 24).then(image => {
if (!map.hasImage('flight-land-icon'))
map.addImage('flight-land-icon', image, { sdf: true });
});
svgToImageAsync(FlightLandFlippedIcon, 24, 24).then(image => {
if (!map.hasImage('flight-land-flipped-icon'))
map.addImage('flight-land-flipped-icon', image, { sdf: true });
});
svgToImageAsync(FlightTakeoffIcon, 24, 24).then(image => {
if (!map.hasImage('flight-takeoff-icon'))
map.addImage('flight-takeoff-icon', image, { sdf: true });
});
svgToImageAsync(FlightTakeoffFlippedIcon, 24, 24).then(image => {
if (!map.hasImage('flight-takeoff-flipped-icon'))
map.addImage('flight-takeoff-flipped-icon', image, { sdf: true });
});
};
const handleLoad = (e: MapboxEvent<undefined>) => {
const map = e.target;
if (map == undefined)
return;
addMapSources(map);
};
const handleStyleData = (e: MapStyleDataEvent) => {
const map = e.target;
if (map == undefined)
return;
addMapSources(map);
};
const handleClick = (e: MapLayerMouseEvent) => {
if (e.features == undefined || e.features.length <= 0)
return;
const selectedFeature = e.features[0] as Feature;
if (selectedFeature.properties) {
const icao24 = selectedFeature.properties['icao24'] as string;
if (icao24)
if (props.onTrackAircraft)
props.onTrackAircraft(icao24);
}
};
const handleMove = (e: ViewStateChangeEvent) => {
setViewState(e.viewState);
const mapGeoBounds = getMapGeoBounds();
if (props.onMapChange)
props.onMapChange(viewState, mapGeoBounds);
};
// Helpers
const defaultMapSettings = {
dragPan: true,
dragRotate: false,
scrollZoom: true,
keyboard: true,
doubleClickZoom: true,
minZoom: 0,
maxZoom: 20,
minPitch: 0,
maxPitch: 85
}
const showDataOverlayOnMap = systemContext.getSetting(SettingKeys.ShowDataOverlayOnMap);
const showLogOverlayOnMap = systemContext.getSetting(SettingKeys.ShowLogOverlayOnMap);
return (
<ReactMap
ref={mapRef}
style={{
width: '100%',
height: '100%'
}}
{...viewState}
{...defaultMapSettings}
interactiveLayerIds={[
aircraftLayerId
]}
mapStyle={styleTheme.map.style}
mapboxAccessToken={process.env.REACT_APP_MAPBOX_TOKEN}
onLoad={handleLoad}
onClick={handleClick}
onMove={handleMove}
onStyleData={handleStyleData}>
<FullscreenControl
position='bottom-right' />
<NavigationControl
position='bottom-right' />
{showDataOverlayOnMap &&
<Box
sx={{
position: 'absolute',
bottom: 48,
right: 50
}}>
<DataOverlay
stateVectors={props.stateVectors} />
</Box>
}
{showLogOverlayOnMap &&
<Box
sx={{
position: 'absolute',
bottom: 186,
right: 50
}}>
<LogOverlay />
</Box>
}
{props.selectedAircraft &&
<Box
sx={{
position: 'absolute',
bottom: 48,
left: 0,
padding: '10px'
}}>
<AircraftInfoOverlay
selectedAircraft={props.selectedAircraft}
onRelease={props.onReleaseTrack} />
</Box>
}
<AircraftLayer
stateVectors={props.stateVectors}
zoom={viewState.zoom}
selectedAircraft={props.selectedAircraft} />
</ReactMap>
);
}
Example #29
Source File: RotatingRoundWorldMapWithCoordinates.tsx From react-tutorials with MIT License | 4 votes |
RotatingRoundWorldMapWithCoordinates = () => {
const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
const [rotation, setRotation] = useState<number>(initRotation)
const [isRotate, setIsRotate] = useState<Boolean>(false)
useEffect(() => {
fetch('/data/world-110m.json').then((response) => {
if (response.status !== 200) {
// eslint-disable-next-line no-console
console.log(`Houston we have a problem: ${response.status}`)
return
}
response.json().then((worldData) => {
const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
setGeographies(mapFeatures)
})
})
}, [])
// geoEqualEarth
// geoOrthographic
const projection = geoOrthographic().scale(scale).translate([cx, cy]).rotate([rotation, 0])
AnimationFrame(() => {
if (isRotate) {
let newRotation = rotation
if (rotation >= 360) {
newRotation = rotation - 360
}
setRotation(newRotation + 0.2)
// console.log(`rotation: ${ rotation}`)
}
})
function returnProjectionValueWhenValid(point: [number, number], index: number) {
const retVal: [number, number] | null = projection(point)
if (retVal?.length) {
return retVal[index]
}
return 0
}
const handleMarkerClick = (i: number) => {
// eslint-disable-next-line no-alert
alert(`Marker: ${JSON.stringify(data[i])}`)
}
return (
<>
<Button
size="medium"
color="primary"
startIcon={<PlayCircleFilledWhiteIcon />}
onClick={() => {
setIsRotate(true)
}}
/>
<svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
<g>
<circle fill="#f2f2f2" cx={cx} cy={cy} r={scale} />
</g>
<g>
{(geographies as []).map((d, i) => (
<path
key={`path-${uuid()}`}
d={geoPath().projection(projection)(d) as string}
fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
stroke="aliceblue"
strokeWidth={0.5}
/>
))}
</g>
<g>
{data.map((d, i) => (
<circle
key={`marker-${uuid()}`}
cx={returnProjectionValueWhenValid(d.coordinates, 0)}
cy={returnProjectionValueWhenValid(d.coordinates, 1)}
r={5}
fill="#E91E63"
stroke="#FFFFFF"
onClick={() => handleMarkerClick(i)}
onMouseEnter={() => setIsRotate(false)}
/>
))}
</g>
</svg>
</>
)
}