-
-
Notifications
You must be signed in to change notification settings - Fork 23.6k
Military bases mapping with infrastructure data #5663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Military bases mapping with infrastructure data #5663
Conversation
Created an interactive mapping application to visualize US military bases and critical infrastructure including electrical, gas, and water systems. This tool supports analysis for data center and power generation facility site selection. Features: - Interactive map with React-Leaflet and OpenStreetMap - 14 major military installations across all service branches - Power generation facilities (nuclear, fossil fuel, hydro, wind, solar) - Electrical substations and transmission infrastructure - Natural gas hubs and pipeline networks - Water supply infrastructure and aqueducts - Pre-analyzed potential data center sites - Layer controls to toggle infrastructure types - Color-coded markers with detailed popups - Side panel for selected feature details Files added: - packages/ui/src/views/infrastructuremap/index.jsx - Main map component - packages/ui/src/data/infrastructureData.js - Infrastructure datasets - packages/ui/src/api/infrastructure.js - API module for data access - packages/ui/src/views/infrastructuremap/README.md - Feature documentation Files modified: - packages/ui/package.json - Added leaflet and react-leaflet dependencies - packages/ui/src/routes/MainRoutes.jsx - Added /infrastructure route - packages/ui/src/menu-items/dashboard.js - Added Infrastructure Map menu item
Summary of ChangesHello @NikolaManagement, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant new feature: an interactive mapping application designed to aid in strategic site selection. It provides a comprehensive visual overlay of military bases and essential infrastructure like power, gas, and water systems across the US. This tool empowers users to perform detailed analysis for potential data center and power generation facility locations by offering customizable data layers and detailed information on demand. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces an excellent new feature: an interactive map for visualizing US military bases and critical infrastructure. The implementation is well-structured, adding new dependencies, routes, and UI components correctly. The use of a mock API layer over static data is a smart approach that will simplify future transitions to a live backend. My review focuses on a few areas where the code can be made more maintainable by reducing duplication and fixing a minor bug in how data is displayed in the details panel. Overall, this is a solid contribution.
| {selectedFeature.capacity && ( | ||
| <Typography variant="body2"> | ||
| <strong>Capacity:</strong> {selectedFeature.capacity}{' '} | ||
| {selectedFeature.category.includes('Power') ? 'MW' : 'units'} | ||
| </Typography> | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for displaying capacity units in the details panel is not robust. It currently checks if the category includes "Power" to display "MW" and defaults to "units" for everything else. This is incorrect for other infrastructure types like water and gas, which have specific units (cfs, MMcf/day), leading to misleading information being shown to the user.
I suggest using a mapping from category to unit to ensure the correct unit is always displayed. For better performance and readability, this map should be defined as a constant outside the component's render method.
| {selectedFeature.capacity && ( | |
| <Typography variant="body2"> | |
| <strong>Capacity:</strong> {selectedFeature.capacity}{' '} | |
| {selectedFeature.category.includes('Power') ? 'MW' : 'units'} | |
| </Typography> | |
| )} | |
| {selectedFeature.capacity && ( | |
| <Typography variant="body2"> | |
| <strong>Capacity:</strong> {selectedFeature.capacity}{ | |
| ' ' + ({ | |
| 'Nuclear Power': 'MW', | |
| 'Fossil Fuel Power': 'MW', | |
| 'Hydroelectric Power': 'MW', | |
| 'Wind Power': 'MW', | |
| 'Solar Power': 'MW', | |
| 'Natural Gas Hub': 'MMcf/day', | |
| 'Water Supply': 'cfs' | |
| }[selectedFeature.category] || '') | |
| } | |
| </Typography> | |
| )} |
| const getInfrastructureByType = (type) => { | ||
| switch (type) { | ||
| case 'military': | ||
| return getMilitaryBases() | ||
| case 'power': | ||
| return getPowerPlants() | ||
| case 'electrical': | ||
| return getElectricalSubstations() | ||
| case 'gas': | ||
| return getGasInfrastructure() | ||
| case 'water': | ||
| return getWaterInfrastructure() | ||
| case 'datacenter': | ||
| return getDataCenterSites() | ||
| default: | ||
| return getAllInfrastructure() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The switch statement in getInfrastructureByType is functional but verbose. Using a map to associate types with their data-fetching functions would make this code more concise, easier to read, and simpler to extend with new infrastructure types in the future.
const getInfrastructureByType = (type) => {
const typeMap = {
military: getMilitaryBases,
power: getPowerPlants,
electrical: getElectricalSubstations,
gas: getGasInfrastructure,
water: getWaterInfrastructure,
datacenter: getDataCenterSites
}
const getter = typeMap[type]
return getter ? getter() : getAllInfrastructure()
}| const renderMarkers = () => { | ||
| const markers = [] | ||
|
|
||
| if (selectedLayers.militaryBases) { | ||
| militaryBases.forEach((base) => { | ||
| markers.push( | ||
| <Marker | ||
| key={base.id} | ||
| position={base.coordinates} | ||
| icon={createColoredIcon(categoryColors[base.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(base) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{base.name}</strong> | ||
| <br /> | ||
| <em>{base.category}</em> | ||
| <br /> | ||
| State: {base.state} | ||
| <br /> | ||
| Land Area: {base.landArea} sq mi | ||
| <br /> | ||
| Power Capacity: {base.powerCapacity} MW | ||
| <br /> | ||
| Water Access: {base.waterAccess} | ||
| <br /> | ||
| <small>{base.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| if (selectedLayers.powerPlants) { | ||
| powerPlants.forEach((plant) => { | ||
| markers.push( | ||
| <Marker | ||
| key={plant.id} | ||
| position={plant.coordinates} | ||
| icon={createColoredIcon(categoryColors[plant.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(plant) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{plant.name}</strong> | ||
| <br /> | ||
| <em>{plant.category}</em> | ||
| <br /> | ||
| State: {plant.state} | ||
| <br /> | ||
| Capacity: {plant.capacity} MW | ||
| <br /> | ||
| Fuel Type: {plant.fuelType} | ||
| <br /> | ||
| <small>{plant.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| if (selectedLayers.electricalSubstations) { | ||
| electricalSubstations.forEach((substation) => { | ||
| markers.push( | ||
| <Marker | ||
| key={substation.id} | ||
| position={substation.coordinates} | ||
| icon={createColoredIcon(categoryColors[substation.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(substation) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{substation.name}</strong> | ||
| <br /> | ||
| <em>{substation.category}</em> | ||
| <br /> | ||
| State: {substation.state} | ||
| <br /> | ||
| Voltage: {substation.voltage} kV | ||
| <br /> | ||
| <small>{substation.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| if (selectedLayers.gasInfrastructure) { | ||
| gasInfrastructure.forEach((gas) => { | ||
| markers.push( | ||
| <Marker | ||
| key={gas.id} | ||
| position={gas.coordinates} | ||
| icon={createColoredIcon(categoryColors[gas.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(gas) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{gas.name}</strong> | ||
| <br /> | ||
| <em>{gas.category}</em> | ||
| <br /> | ||
| State: {gas.state} | ||
| <br /> | ||
| {gas.capacity && ( | ||
| <> | ||
| Capacity: {gas.capacity} MMcf/day | ||
| <br /> | ||
| </> | ||
| )} | ||
| <small>{gas.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| if (selectedLayers.waterInfrastructure) { | ||
| waterInfrastructure.forEach((water) => { | ||
| markers.push( | ||
| <Marker | ||
| key={water.id} | ||
| position={water.coordinates} | ||
| icon={createColoredIcon(categoryColors[water.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(water) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{water.name}</strong> | ||
| <br /> | ||
| <em>{water.category}</em> | ||
| <br /> | ||
| State: {water.state} | ||
| <br /> | ||
| Capacity: {water.capacity} cfs | ||
| <br /> | ||
| <small>{water.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| if (selectedLayers.dataCenterSites) { | ||
| dataCenterSites.forEach((site) => { | ||
| markers.push( | ||
| <Marker | ||
| key={site.id} | ||
| position={site.coordinates} | ||
| icon={createColoredIcon(categoryColors[site.category])} | ||
| eventHandlers={{ | ||
| click: () => handleFeatureClick(site) | ||
| }} | ||
| > | ||
| <Popup> | ||
| <div> | ||
| <strong>{site.name}</strong> | ||
| <br /> | ||
| <em>{site.category}</em> | ||
| <br /> | ||
| State: {site.state} | ||
| <br /> | ||
| Score: {site.score}/100 | ||
| <br /> | ||
| Power: {site.powerAvailability} | ||
| <br /> | ||
| Water: {site.waterAvailability} | ||
| <br /> | ||
| Fiber: {site.fiberConnectivity} | ||
| <br /> | ||
| Nearby Military: {site.nearbyMilitary} | ||
| <br /> | ||
| <small>{site.notes}</small> | ||
| </div> | ||
| </Popup> | ||
| </Marker> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| return markers | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The renderMarkers function has a significant amount of duplicated code for rendering markers for each data type. This reduces maintainability and makes it cumbersome to add new layers.
I recommend refactoring this by using a configuration array for the layers. You can then iterate over this configuration to generate the markers, which will centralize the rendering logic and simplify future modifications.
Here's an example of how you could structure this:
const layerDataSources = {
militaryBases: militaryBases,
powerPlants: powerPlants,
electricalSubstations: electricalSubstations,
gasInfrastructure: gasInfrastructure,
waterInfrastructure: waterInfrastructure,
dataCenterSites: dataCenterSites
};
const renderMarkers = () => {
return Object.entries(selectedLayers).flatMap(([layerKey, isVisible]) => {
if (!isVisible) return [];
const data = layerDataSources[layerKey];
return data.map(item => (
<Marker
key={item.id}
position={item.coordinates}
icon={createColoredIcon(categoryColors[item.category])}
eventHandlers={{ click: () => handleFeatureClick(item) }}
>
{/* A dedicated component for popups would further improve this */}
<Popup>{/* ... popup content ... */}</Popup>
</Marker>
));
});
};
Created an interactive mapping application to visualize US military bases and critical infrastructure including electrical, gas, and water systems. This tool supports analysis for data center and power generation facility site selection.
Features:
Files added:
Files modified: