Skip to content

Commit 7640873

Browse files
authored
Merge pull request #35 from OpenGeoscience/julia-tools
julia tools for conversion
2 parents 7e5facb + 3cb29f1 commit 7640873

5 files changed

Lines changed: 229 additions & 4 deletions

File tree

client/src/components/DataSelection/ContextMap.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import maplibregl, { Map } from 'maplibre-gl';
33
import 'maplibre-gl/dist/maplibre-gl.css';
44
import {
5-
PropType, Ref, defineComponent, onMounted, ref, watch,
5+
PropType, Ref, defineComponent, onMounted, ref, shallowRef, watch,
66
} from 'vue';
77
88
export default defineComponent({
@@ -20,7 +20,7 @@ export default defineComponent({
2020
emits: ['update'],
2121
setup(props, { emit }) {
2222
const mapContainer: Ref<HTMLDivElement | null> = ref(null);
23-
const map: Ref<null | Map> = ref(null);
23+
const map: Ref<null | Map> = shallowRef(null);
2424
const mapLoaded = ref(false);
2525
const emitData = () => {
2626
if (map.value) {

client/src/components/Map.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import maplibregl, { Map, VectorTileSource } from 'maplibre-gl';
33
import 'maplibre-gl/dist/maplibre-gl.css';
44
import { Protocol as PMTilesProtocol } from 'pmtiles';
55
import {
6-
Ref, defineComponent, onMounted, ref, watch,
6+
Ref, defineComponent, onMounted, ref, shallowRef, watch,
77
} from 'vue';
88
import MapStore from '../MapStore';
99
import {
@@ -53,7 +53,7 @@ export default defineComponent({
5353
},
5454
setup() {
5555
const mapContainer: Ref<HTMLDivElement | null> = ref(null);
56-
const map: Ref<null | Map> = ref(null);
56+
const map: Ref<null | Map> = shallowRef(null);
5757
const mapAlert = ref(false);
5858
const mapAlertMessage = ref('');
5959

scripts/julia/jld2_to_json.jl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env julia
2+
3+
using ArgParse
4+
using JLD2
5+
using JSON
6+
using DataFrames # Required to properly handle DataFrame
7+
8+
"""
9+
Recursively convert JLD2 data to something JSON-serializable.
10+
Unsupported types are replaced with string descriptions.
11+
"""
12+
function safe_serialize(obj)
13+
if isa(obj, Number) || isa(obj, String) || isa(obj, Bool) || obj === nothing
14+
return obj
15+
elseif isa(obj, AbstractArray)
16+
return [safe_serialize(x) for x in obj]
17+
elseif isa(obj, Dict)
18+
return Dict(string(k) => safe_serialize(v) for (k, v) in obj)
19+
elseif isa(obj, DataFrame)
20+
# Serialize the DataFrame to a Dict of column names and values (for JSON compatibility)
21+
return Dict("columns" => names(obj), "data" => Matrix(obj))
22+
else
23+
return JSON.lower(obj) # Try JSON-compatible lowering for other types
24+
end
25+
end
26+
27+
function jld2_to_json(jld2_path::String, json_path::String)
28+
println("Reading from $jld2_path ...")
29+
jld_data = jldopen(jld2_path, "r")
30+
31+
result = Dict{String, Any}()
32+
33+
for k in keys(jld_data)
34+
println("Processing key: $k")
35+
# Ensure that we're processing the reconstructed DataFrame properly
36+
value = jld_data[k]
37+
38+
# If it's a DataFrame, we need to serialize it differently
39+
result[string(k)] = safe_serialize(value)
40+
end
41+
42+
close(jld_data)
43+
44+
println("Writing to $json_path ...")
45+
open(json_path, "w") do io
46+
JSON.print(io, result)
47+
end
48+
49+
println("Conversion complete.")
50+
end
51+
52+
function main()
53+
s = ArgParseSettings()
54+
@add_arg_table s begin
55+
"input"
56+
help = "Input JLD2 file path"
57+
required = true
58+
"--output", "-o"
59+
help = "Output JSON file path"
60+
required = true
61+
end
62+
63+
parsed_args = parse_args(s)
64+
65+
input_file = parsed_args["input"]
66+
output_file = parsed_args["output"]
67+
68+
jld2_to_json(input_file, output_file)
69+
end
70+
71+
main()

scripts/julia/juliaJSON2GEOJSON.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import click
2+
import json
3+
from shapely.geometry import Point, mapping
4+
5+
@click.command()
6+
@click.argument('json_file', type=click.Path(exists=True))
7+
@click.argument('output_geojson', type=click.Path())
8+
def json_to_geojson(json_file, output_geojson):
9+
# Load JSON data
10+
with open(json_file, 'r') as f:
11+
data = json.load(f)
12+
13+
# Extract DataFrame
14+
dataframe = data['Dataframe']
15+
columns = dataframe['columns']
16+
data_array = dataframe['data']
17+
18+
# Ensure all columns have the same length
19+
num_rows = len(data_array[0]) # Number of rows (values per column)
20+
for column_data in data_array:
21+
if len(column_data) != num_rows:
22+
raise ValueError("Not all columns in data_array have the same number of values.")
23+
24+
# Find latitude and longitude columns
25+
lat_index = columns.index('Lat')
26+
lon_index = columns.index('Lon')
27+
28+
# Create GeoJSON features
29+
features = []
30+
for i in range(num_rows):
31+
latitude = data_array[lat_index][i]
32+
longitude = data_array[lon_index][i]
33+
34+
# Create properties dictionary for each feature
35+
properties = {
36+
columns[j]: data_array[j][i]
37+
for j in range(len(columns)) if j != lat_index and j != lon_index
38+
}
39+
40+
# Create Point geometry for each feature
41+
geometry = Point(longitude, latitude)
42+
43+
# Construct feature
44+
feature = {
45+
'type': 'Feature',
46+
'geometry': mapping(geometry),
47+
'properties': properties
48+
}
49+
features.append(feature)
50+
51+
# Create GeoJSON structure
52+
geojson = {
53+
'type': 'FeatureCollection',
54+
'features': features
55+
}
56+
57+
# Write to GeoJSON file
58+
with open(output_geojson, 'w') as f:
59+
json.dump(geojson, f, indent=2)
60+
61+
click.echo(f"GeoJSON file saved to {output_geojson}")
62+
63+
if __name__ == '__main__':
64+
json_to_geojson()
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import click
2+
import csv
3+
import json
4+
import re
5+
from datetime import datetime
6+
from shapely.wkb import loads
7+
from shapely.geometry import Point
8+
9+
10+
import re
11+
from datetime import datetime
12+
13+
def convert_to_unix_time(datetime_str):
14+
"""Convert a datetime string to a Unix timestamp, extracting only YYYY-MM-DD HH:MM:SS."""
15+
try:
16+
# Step 1: Use regex to extract the part of the datetime string in the format YYYY-MM-DD HH:MM:SS
17+
match = re.match(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})', datetime_str)
18+
if match:
19+
datetime_str = match.group(0) # Extract the matched part
20+
21+
# Step 2: Convert the string to a datetime object
22+
dt = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
23+
24+
# Step 3: Return Unix timestamp
25+
return int(dt.timestamp())
26+
27+
except ValueError as e:
28+
print(f"Error parsing datetime: {datetime_str}")
29+
raise e
30+
31+
@click.command()
32+
@click.argument('csv_file', type=click.Path(exists=True))
33+
@click.argument('geojson_file', type=click.Path())
34+
def csv_to_geojson(csv_file, geojson_file):
35+
"""Convert CSV to GeoJSON with specific formatting and handling of NULL values."""
36+
37+
features = []
38+
39+
with open(csv_file, newline='', encoding='utf-8') as csvfile:
40+
reader = csv.DictReader(csvfile)
41+
42+
for row in reader:
43+
# Skip row if coordinates are NULL
44+
if row['coordinates'] == 'NULL':
45+
continue
46+
47+
# Parse WKT coordinates into GeoJSON Point
48+
point = loads(row['coordinates'])
49+
50+
# Create properties dictionary
51+
properties = {}
52+
for key, value in row.items():
53+
if value != 'NULL':
54+
if key == 'start_datetime':
55+
# Add original start_datetime
56+
properties['start_datetime'] = value
57+
print(value)
58+
# Convert to unix_time and add it to properties
59+
properties['unix_time'] = convert_to_unix_time(value)
60+
elif key in ['depth', 'magnitude']:
61+
# Set to 0 if value is NULL
62+
properties[key] = float(value) if value != 'NULL' else 0
63+
else:
64+
properties[key] = value
65+
66+
# Create feature
67+
feature = {
68+
"type": "Feature",
69+
"geometry": {
70+
"type": "Point",
71+
"coordinates": [point.x, point.y]
72+
},
73+
"properties": properties
74+
}
75+
76+
features.append(feature)
77+
78+
# Create the GeoJSON structure
79+
geojson = {
80+
"type": "FeatureCollection",
81+
"features": features
82+
}
83+
84+
# Write to output GeoJSON file
85+
with open(geojson_file, 'w', encoding='utf-8') as outfile:
86+
json.dump(geojson, outfile, indent=4)
87+
88+
89+
if __name__ == '__main__':
90+
csv_to_geojson()

0 commit comments

Comments
 (0)