Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions site/src/DownloadCatalog.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// URL for the remote manifest file
const STAC_URL = 'https://labs.overturemaps.org/stac/catalog.json'
const STAC_URL = 'https://stac.overturemaps.org/catalog.json'

// Cache the manifest to avoid repeated fetches
let cachedManifest = null;
Expand All @@ -24,7 +24,7 @@ async function fetchManifest() {
})
.then(stacData => {
const latest = stacData.latest;
return fetch(`https://labs.overturemaps.org/stac/${latest}/manifest.geojson`);
return fetch(`https://stac.overturemaps.org/${latest}/manifest.geojson`);
})
.then(response => {
if (!response.ok) {
Expand Down
5 changes: 4 additions & 1 deletion site/src/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ import { layers } from "./Layers";
import ThemeTypeLayer from "./ThemeTypeLayer";
import FeaturePopup from "./FeatureSelector";

// Fetch the latest Overture release from Overture STAC
const LATEST_RELEASE = await fetch('https://stac.overturemaps.org/catalog.json').then(r => r.json()).then(r => r.latest.split('.')[0])

const PMTILES_URL =
"pmtiles://https://d3c1b7bog2u1nn.cloudfront.net/2025-07-23/";
"pmtiles://https://d3c1b7bog2u1nn.cloudfront.net/" + LATEST_RELEASE + "/";

const INITIAL_VIEW_STATE = {
latitude: 38.90678,
Expand Down
2 changes: 1 addition & 1 deletion site/src/inspector_panel/InspectorPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function InspectorPanel({
return (
<div className="inspector-panel">
<div className="panel-header">
<h4 className="title">Inspector Panel</h4>
<h6 className="title">Inspector Panel</h6>
<button
className="close-panel-button"
onClick={() => {
Expand Down
26 changes: 26 additions & 0 deletions site/src/inspector_panel/NamesRow.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.name-content {
margin-left: 20px;
}

.name-content p {
margin: 2px 0 !important;
line-height: 1.3;
padding: 0;
}

.name-content strong {
font-size: 11px;
font-weight: 500;
color: #64748b;
}

.name-divider {
margin: 2px 0;
border-top: 1px solid var(--ifm-table-border-width) solid
var(--ifm-table-border-color);
}

.panel-row.names {
overflow: auto;
max-height: 200px;
}
147 changes: 147 additions & 0 deletions site/src/inspector_panel/NamesRow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import "./NamesRow.css";

function NamesRow({ entity, mode }) {
const names = JSON.parse(entity["names"]);

// Function to check if a value is a URL
const isURL = (value) => {
if (!value || typeof value !== 'string') return false;
try {
const url = new URL(value);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch {
return false;
}
};

// Function to render a single URL as a clickable link
const renderURL = (url) => (
<a
href={url}
target="_blank"
rel="noopener noreferrer"
style={{
color: '#3b82f6',
textDecoration: 'underline',
wordBreak: 'break-all'
}}
>
{url}
</a>
);

// Function to render value as link or text, handling arrays and objects
const renderValue = (value) => {
// Handle null/undefined
if (value == null) return 'null';

// Handle strings first to check for JSON
const stringValue = value.toString();

// Try to parse as JSON if it looks like an array or object
if ((stringValue.startsWith('[') && stringValue.endsWith(']')) ||
(stringValue.startsWith('{') && stringValue.endsWith('}'))) {
try {
const parsed = JSON.parse(stringValue);
return renderValue(parsed);
} catch {
// If parsing fails, fall through to regular string handling
}
}

// Handle arrays - render inline for simple arrays, nested for complex ones
if (Array.isArray(value)) {
if (value.length === 0) return '[]';

// Check if all items are URLs
const allURLs = value.every(item => isURL(item));

// Check if all items are simple (strings, numbers, booleans)
const allSimple = value.every(item =>
typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean'
);

if (allURLs) {
// Render URL arrays as clickable links
return (
<div className="nested-content">
{value.map((item, index) => (
<div key={index} className="nested-item">
{renderURL(item)}
</div>
))}
</div>
);
} else if (allSimple && value.length <= 3) {
// Render simple arrays inline
return `[${value.join(', ')}]`;
}

// Render complex or long arrays nested
return (
<div className="nested-content">
{value.map((item, index) => (
<div key={index} className="nested-item">
{renderValue(item)}
</div>
))}
</div>
);
}

// Handle objects
if (typeof value === 'object') {
const entries = Object.entries(value);
if (entries.length === 0) return '{}';

return (
<div className="nested-content">
{entries.map(([key, val]) => (
<div key={key} className="nested-item">
<span className="nested-key">
{key}:
</span>{' '}
{renderValue(val)}
</div>
))}
</div>
);
}

// Check if it's a URL
if (isURL(stringValue)) {
return renderURL(stringValue);
}

return stringValue;
};

return (
<div className="panel-row names">
<div>
<strong>names: </strong>
<div className="name-content">
{names.primary != null ? (
<p><strong>primary: </strong>{names.primary}</p>
) : (
<></>
)}

{names.common != null ? (
<p><strong>common: </strong>{renderValue(names.common)}</p>
) : (
<></>
)}

{names.rules != null ? (
<p><strong>rules: </strong>{renderValue(names.rules)}</p>
) : (
<></>
)}
</div>
</div>
</div>
);
}

export default NamesRow;
20 changes: 20 additions & 0 deletions site/src/inspector_panel/SourcesRow.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
margin-left: 20px;
}

.sources-content > div {
margin-bottom: 8px;
}

.sources-content > div:last-child {
margin-bottom: 0;
}

.sources-content > div > div {
margin: 2px 0 !important;
line-height: 1.3;
padding: 0;
}

.sources-content strong {
font-size: 11px;
font-weight: 500;
color: #64748b;
}

.source-divider {
margin: 2px 0;
border-top: 1px solid var(--ifm-table-border-width) solid
Expand Down
6 changes: 6 additions & 0 deletions site/src/inspector_panel/SourcesRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ function SourcesRow({ entity, mode, tips }) {
{source.property}
</div>
)}
{source.between && (
<div>
<strong>between: </strong>
{source.between}
</div>
)}
{index < sources.length - 1 && (
<hr className="source-divider" />
)}
Expand Down
75 changes: 34 additions & 41 deletions site/src/inspector_panel/TableRow.css
Original file line number Diff line number Diff line change
@@ -1,65 +1,58 @@
.inspector-panel {
td {
padding: 5px;
padding: 2px 0;
}

td {
padding-right: 8px;
vertical-align: top;
border-left: 0;
border-right: 0;
word-break: break-all;
font-size: 13px;
}

td:first-child {
text-align: left;
width: 40%;
word-break: normal;
text-align: right;
min-width: fit-content;
max-width: 120px;
word-break: keep-all;
white-space: nowrap;
border: none;
padding-right: 6px;
width: 1%;
font-size: 11px;
font-weight: 500;
color: #64748b;
}

td:last-child {
overflow: hidden;
width: 60%;
border: none;
word-break: break-word;
width: 99%;
}

tr {
border-top: none;
border-bottom: var(--ifm-table-border-width) solid
var(--ifm-table-border-color);
border-bottom: 1px solid var(--border-color-light);
}

td.expanded {
max-height: unset;
white-space: normal;
}

td.collapsed {
max-height: 26px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}

button.expand {
border: none;
border-radius: 50%;
padding: 0;
height: 26px;
width: 26px;
justify-content: center;
background-color: unset;
}

button.expand:focus {
outline: none;
/* Nested content styling */
.nested-content {
margin-left: 8px;
border-left: 1px solid #e2e8f0;
padding-left: 6px;
margin-top: 2px;
}

div.first-child {
display: flex;
justify-content: space-between;
padding-right: 10px;
.nested-item {
margin: 1px 0;
line-height: 1.3;
font-size: 12px;
}

svg.ec-icon {
padding-top: 1px;
fill: var(--ifm-color-secondary-darkest);
.nested-key {
color: #64748b;
font-size: 11px;
font-weight: 500;
margin-right: 3px;
}
Loading
Loading