Add clickable SVG links
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
7c954242eb
commit
2610a54fe1
4 changed files with 89 additions and 21 deletions
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
{"Erlangen": [11.0028028, 49.6000372], "Paderborn": [8.7479251, 51.7171873], "Hamburg": [9.9443486, 53.5583644], "Aachen": [6.091774700480718, 50.7715109], "Basel": [7.6342977, 47.5323068], "Berlin": [13.38283, 52.5217046], "Bremen": [8.7879452, 53.0864586], "K\u00f6ln": [6.912896, 50.9505492], "Darmstadt": [8.6511275, 49.8708409], "Dresden": [13.7288095, 51.0811269], "D\u00fcsseldorf": [6.7996122, 51.2125738], "Frankfurt am Main": [8.6362035, 50.1241797], "Freiburg": [7.8405746483681735, 47.99297755], "G\u00f6ttingen": [9.9446185, 51.5453725], "Hannover": [9.717936908887404, 52.38812135], "Karlsruhe": [8.4073787, 49.0066019], "Mannheim": [8.4886818, 49.4636517], "M\u00fcnchen": [11.5607949, 48.153629], "Salzburg": [13.0561199, 47.7939873], "Stuttgart": [9.1800132, 48.7784485], "Ulm": [9.9910884, 48.4005863], "Wien": [16.35611792351422, 48.209451099999995], "Wiesbaden": [8.2295012, 50.0831784], "Z\u00fcrich": [8.5203159, 47.3869751], "Siegen": [8.0044503, 50.8689203], "Kaiserslautern": [7.762277299724986, 49.44049735], "Essen": [7.024639594585695, 51.43860565], "Dortmund": [7.464966783180763, 51.52768425], "Fulda": [9.6775152, 50.5588931], "W\u00fcrzburg": [9.923678752181619, 49.80223915], "Bamberg": [10.89268892402827, 49.90189135], "Kassel": [9.484939, 51.3183203]}
|
||||
{"Erlangen": {"location": [11.0028028, 49.6000372], "web": "https://erlangen.ccc.de/", "name": "Bits'n'Bugs"}, "Paderborn": {"location": [8.7479251, 51.7171873], "web": "https://c3pb.de/", "name": "Chaos Computer Club Paderborn"}, "Hamburg": {"location": [9.9443486, 53.5583644], "web": "https://hamburg.ccc.de/", "name": "Chaos Computer Club Hamburg"}, "Aachen": {"location": [6.091774700480718, 50.7715109], "web": "https://aachen.ccc.de/", "name": "Chaos Computer Club Aachen"}, "Basel": {"location": [7.6342977, 47.5323068], "web": "https://www.ccc-basel.ch/", "name": "Chaos Computer Club Basel"}, "Berlin": {"location": [13.38283, 52.5217046], "web": "https://berlin.ccc.de/", "name": "Chaos Computer Club Berlin"}, "Bremen": {"location": [8.7879452, 53.0864586], "web": "https://ccchb.de/", "name": "Chaos Computer Club Bremen"}, "K\u00f6ln": {"location": [6.912896, 50.9505492], "web": "https://koeln.ccc.de/", "name": "Chaos Computer Club Cologne"}, "Darmstadt": {"location": [8.6511275, 49.8708409], "web": "https://www.chaos-darmstadt.de/", "name": "Chaos Computer Club Darmstadt"}, "Dresden": {"location": [13.7288095, 51.0811269], "web": "https://c3d2.de/", "name": "Chaos Computer Club Dresden"}, "D\u00fcsseldorf": {"location": [6.7996122, 51.2125738], "web": "https://chaosdorf.de/", "name": "Chaos Computer Club D\u00fcsseldorf"}, "Frankfurt am Main": {"location": [8.6362035, 50.1241797], "web": "https://ccc-ffm.de/", "name": "Chaos Computer Club Frankfurt"}, "Freiburg": {"location": [7.8405746483681735, 47.99297755], "web": "https://cccfr.de/", "name": "Chaos Computer Club Freiburg"}, "G\u00f6ttingen": {"location": [9.9446185, 51.5453725], "web": "https://cccgoe.de/", "name": "Chaos Computer Club G\u00f6ttingen"}, "Hannover": {"location": [9.717936908887404, 52.38812135], "web": "https://hannover.ccc.de/", "name": "Chaos Computer Club Hannover"}, "Karlsruhe": {"location": [8.4073787, 49.0066019], "web": "https://entropia.de/", "name": "Chaos Computer Club Karlsruhe"}, "Mannheim": {"location": [8.4886818, 49.4636517], "web": "https://www.ccc-mannheim.de/", "name": "Chaos Computer Club Mannheim"}, "M\u00fcnchen": {"location": [11.5607949, 48.153629], "web": "https://www.muc.ccc.de/", "name": "Chaos Computer Club M\u00fcnchen"}, "Salzburg": {"location": [13.0561199, 47.7939873], "web": "https://cccsbg.at", "name": "Chaos Computer Club Salzburg"}, "Stuttgart": {"location": [9.1800132, 48.7784485], "web": "https://cccs.de/", "name": "Chaos Computer Club Stuttgart"}, "Ulm": {"location": [9.9910884, 48.4005863], "web": "https://ulm.ccc.de/", "name": "Chaos Computer Club Ulm"}, "Wien": {"location": [16.35611792351422, 48.209451099999995], "web": "https://c3w.at/", "name": "Chaos Computer Club Wien"}, "Wiesbaden": {"location": [8.2295012, 50.0831784], "web": "https://cccwi.de/", "name": "Chaos Computer Club Wiesbaden"}, "Z\u00fcrich": {"location": [8.5203159, 47.3869751], "web": "https://www.ccczh.ch/", "name": "Chaos Computer Club Z\u00fcrich"}, "Siegen": {"location": [8.0044503, 50.8689203], "web": "https://chaos-siegen.de/", "name": "Chaos Computer Club Siegen"}, "Kaiserslautern": {"location": [7.762277299724986, 49.44049735], "web": "http://www.chaos-inkl.de", "name": "Chaos inKL."}, "Essen": {"location": [7.024639594585695, 51.43860565], "web": "https://chaospott.de/"}, "Dortmund": {"location": [7.464966783180763, 51.52768425], "web": "https://www.chaostreff-dortmund.de/", "name": "Chaostreff Dortmund"}, "L\u00fcbeck": {"location": [10.6713232, 53.8687751], "web": "https://chaotikum.org/", "name": "Chaotikum"}, "Fulda": {"location": [9.6775152, 50.5588931], "web": "https://maglab.space/", "name": "Magrathea Laboratoratories"}, "W\u00fcrzburg": {"location": [9.923678752181619, 49.80223915], "web": "https://nerd2nerd.org/", "name": "Nerd2Nerd"}, "Bamberg": {"location": [10.89268892402827, 49.90189135], "web": "https://www.hackerspace-bamberg.de/", "name": "backspace"}, "Kassel": {"location": [9.484939, 51.3183203], "web": "https://flipdot.org/", "name": "flipdot"}}
|
|
@ -37,9 +37,9 @@ class CachePaths:
|
|||
self.chaostreff_info = os.path.join(path, 'chaostreff-info.json')
|
||||
|
||||
|
||||
ERFA_URL = 'https://doku.ccc.de/Spezial:Semantische_Suche/format%3Djson/limit%3D50/link%3Dall/headers%3Dshow/searchlabel%3DJSON/class%3Dsortable-20wikitable-20smwtable/sort%3D/order%3Dasc/offset%3D0/-5B-5BKategorie:Erfa-2DKreise-5D-5D-20-5B-5BChaostreff-2DActive::wahr-5D-5D/-3FChaostreff-2DCity/-3FChaostreff-2DPhysical-2DAddress/-3FChaostreff-2DPhysical-2DHousenumber/-3FChaostreff-2DPhysical-2DPostcode/-3FChaostreff-2DPhysical-2DCity/-3FChaostreff-2DCountry/mainlabel%3D/prettyprint%3Dtrue/unescape%3Dtrue'
|
||||
ERFA_URL = 'https://doku.ccc.de/Spezial:Semantische_Suche/format%3Djson/limit%3D50/link%3Dall/headers%3Dshow/searchlabel%3DJSON/class%3Dsortable-20wikitable-20smwtable/sort%3D/order%3Dasc/offset%3D0/-5B-5BKategorie:Erfa-2DKreise-5D-5D-20-5B-5BChaostreff-2DActive::wahr-5D-5D/-3FChaostreff-2DCity/-3FChaostreff-2DPhysical-2DAddress/-3FChaostreff-2DPhysical-2DHousenumber/-3FChaostreff-2DPhysical-2DPostcode/-3FChaostreff-2DPhysical-2DCity/-3FChaostreff-2DCountry/-3FPublic-2DWeb/-3FChaostreff-2DLongname/mainlabel%3D/prettyprint%3Dtrue/unescape%3Dtrue'
|
||||
|
||||
CHAOSTREFF_URL = 'https://doku.ccc.de/Spezial:Semantische_Suche/format%3Djson/limit%3D50/link%3Dall/headers%3Dshow/searchlabel%3DJSON/class%3Dsortable-20wikitable-20smwtable/sort%3D/order%3Dasc/offset%3D0/-5B-5BKategorie:Chaostreffs-5D-5D-20-5B-5BChaostreff-2DActive::wahr-5D-5D/-3FChaostreff-2DCity/-3FChaostreff-2DPhysical-2DAddress/-3FChaostreff-2DPhysical-2DHousenumber/-3FChaostreff-2DPhysical-2DPostcode/-3FChaostreff-2DPhysical-2DCity/-3FChaostreff-2DCountry/mainlabel%3D/prettyprint%3Dtrue/unescape%3Dtrue'
|
||||
CHAOSTREFF_URL = 'https://doku.ccc.de/Spezial:Semantische_Suche/format%3Djson/limit%3D50/link%3Dall/headers%3Dshow/searchlabel%3DJSON/class%3Dsortable-20wikitable-20smwtable/sort%3D/order%3Dasc/offset%3D0/-5B-5BKategorie:Chaostreffs-5D-5D-20-5B-5BChaostreff-2DActive::wahr-5D-5D/-3FChaostreff-2DCity/-3FChaostreff-2DPhysical-2DAddress/-3FChaostreff-2DPhysical-2DHousenumber/-3FChaostreff-2DPhysical-2DPostcode/-3FChaostreff-2DPhysical-2DCity/-3FChaostreff-2DCountry/-3FPublic-2DWeb/-3FChaostreff-2DLongname/mainlabel%3D/prettyprint%3Dtrue/unescape%3Dtrue'
|
||||
|
||||
|
||||
def sparql_query(query):
|
||||
|
@ -205,7 +205,12 @@ def fetch_erfas(target, url):
|
|||
if location is None:
|
||||
print(f'WARNING: No location for {name}')
|
||||
city = erfa['printouts']['Chaostreff-City'][0]
|
||||
erfas[city] = location
|
||||
erfas[city] = {'location': location}
|
||||
if len(erfa['printouts']['Public-Web']) > 0:
|
||||
erfas[city]['web'] = erfa['printouts']['Public-Web'][0]
|
||||
if len(erfa['printouts']['Chaostreff-Longname']) > 0:
|
||||
erfas[city]['name'] = erfa['printouts']['Chaostreff-Longname'][0]
|
||||
|
||||
with open(target, 'w') as f:
|
||||
json.dump(erfas, f)
|
||||
|
||||
|
@ -222,7 +227,10 @@ def compute_bbox(ns):
|
|||
for path in tqdm.tqdm([ns.cache_directory.erfa_info, ns.cache_directory.chaostreff_info]):
|
||||
with open(path, 'r') as f:
|
||||
erfadata = json.load(f)
|
||||
for lon, lat in erfadata.values():
|
||||
for data in erfadata.values():
|
||||
if 'location' not in data:
|
||||
continue
|
||||
lon, lat = data['location']
|
||||
if len(bounds) == 0:
|
||||
bounds.append(lon)
|
||||
bounds.append(lat)
|
||||
|
@ -561,18 +569,30 @@ def create_svg(ns, bbox):
|
|||
shapes_countries.append((name, ts))
|
||||
|
||||
erfas = {}
|
||||
erfa_urls = {}
|
||||
erfa_names = {}
|
||||
with open(ns.cache_directory.erfa_info, 'r') as f:
|
||||
ctdata = json.load(f)
|
||||
for city, location in ctdata.items():
|
||||
for city, data in ctdata.items():
|
||||
location = data.get('location')
|
||||
if location is None:
|
||||
continue
|
||||
xt, yt = transformer.transform(*location)
|
||||
erfas[city] = (xt*scalex - origin[0], origin[1] - yt*scaley)
|
||||
web = data.get('web')
|
||||
if web is not None:
|
||||
erfa_urls[city] = web
|
||||
name = data.get('name')
|
||||
if name is not None:
|
||||
erfa_names[city] = name
|
||||
|
||||
chaostreffs = {}
|
||||
chaostreff_urls = {}
|
||||
chaostreff_names = {}
|
||||
with open(ns.cache_directory.chaostreff_info, 'r') as f:
|
||||
ctdata = json.load(f)
|
||||
for city, location in ctdata.items():
|
||||
for city, data in ctdata.items():
|
||||
location = data.get('location')
|
||||
if location is None:
|
||||
continue
|
||||
if city in erfas:
|
||||
|
@ -582,7 +602,12 @@ def create_svg(ns, bbox):
|
|||
continue
|
||||
xt, yt = transformer.transform(*location)
|
||||
chaostreffs[city] = (xt*scalex - origin[0], origin[1] - yt*scaley)
|
||||
|
||||
web = data.get('web')
|
||||
if web is not None:
|
||||
chaostreff_urls[city] = web
|
||||
name = data.get('name')
|
||||
if name is not None:
|
||||
chaostreff_names[city] = name
|
||||
|
||||
rectbox = [0, 0, svg_box[0], svg_box[1]]
|
||||
for name, shape in shapes_states + shapes_countries:
|
||||
|
@ -598,6 +623,9 @@ def create_svg(ns, bbox):
|
|||
viewBox=f'0 0 {svg_box[0]} {svg_box[1]}',
|
||||
width=str(svg_box[0]), height=str(svg_box[1]))
|
||||
|
||||
print('Layouting labels')
|
||||
texts = optimize_text_layout(ns, erfas, chaostreffs, (int(svg_box[0]), int(svg_box[1])), svg)
|
||||
|
||||
defs = etree.Element('defs')
|
||||
style = etree.Element('style', type='text/css')
|
||||
style.text = f'@import url({ns.stylesheet})'
|
||||
|
@ -629,27 +657,42 @@ def create_svg(ns, bbox):
|
|||
svg.append(poly)
|
||||
|
||||
for city, location in erfas.items():
|
||||
box = texts[city]
|
||||
if city in erfa_urls:
|
||||
group = etree.Element('a', href=erfa_urls[city], target='_blank')
|
||||
else:
|
||||
group = etree.Element('g')
|
||||
group.set('data-erfa', city)
|
||||
circle = etree.Element('circle', cx=str(location[0]), cy=str(location[1]), r=str(ns.dotsize_erfa))
|
||||
circle.set('class', 'erfa')
|
||||
circle.set('data-erfa', city)
|
||||
svg.append(circle)
|
||||
if city in erfa_names:
|
||||
title = etree.Element('title')
|
||||
title.text = erfa_names[city]
|
||||
circle.append(title)
|
||||
group.append(circle)
|
||||
text = etree.Element('text', x=str(box.left), y=str(box.top + box.meta['baseline']))
|
||||
text.set('class', 'erfalabel')
|
||||
text.set('data-erfa', city)
|
||||
text.text = box.meta['text']
|
||||
group.append(text)
|
||||
svg.append(group)
|
||||
|
||||
for city, location in chaostreffs.items():
|
||||
circle = etree.Element('circle', cx=str(location[0]), cy=str(location[1]), r=str(ns.dotsize_treff))
|
||||
circle.set('class', 'chaostreff')
|
||||
circle.set('data-chaostreff', city)
|
||||
if city in chaostreff_names:
|
||||
title = etree.Element('title')
|
||||
title.text = chaostreff_names[city]
|
||||
circle.append(title)
|
||||
if city in chaostreff_urls:
|
||||
a = etree.Element('a', href=chaostreff_urls[city], target='_blank', title='foox')
|
||||
a.append(circle)
|
||||
svg.append(a)
|
||||
else:
|
||||
svg.append(circle)
|
||||
|
||||
|
||||
print('Layouting labels')
|
||||
texts = optimize_text_layout(ns, erfas, chaostreffs, (int(svg_box[0]), int(svg_box[1])), svg)
|
||||
for city, box in texts.items():
|
||||
text = etree.Element('text', x=str(box.left), y=str(box.top + box.meta['baseline']))
|
||||
text.set('class', 'erfalabel')
|
||||
text.set('data-erfa', city)
|
||||
text.text = box.meta['text']
|
||||
svg.append(text)
|
||||
|
||||
print('Done, writing SVG')
|
||||
with open('map.svg', 'wb') as mapfile:
|
||||
root = etree.ElementTree(svg)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
|
||||
|
||||
rect.background {
|
||||
fill: #759eb5;
|
||||
stroke: none;
|
||||
|
@ -16,12 +18,32 @@ polygon.state {
|
|||
stroke-width: 3;
|
||||
}
|
||||
|
||||
circle.erfa {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
circle.chaostreff {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
circle.erfa, circle.chaostreff {
|
||||
fill: #f47e1e;
|
||||
stroke: #ffffff;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
a > circle, a > text {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:hover > circle {
|
||||
fill: #5b8ca7;
|
||||
}
|
||||
|
||||
a:hover > text {
|
||||
fill: #5b8ca7;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'concertone';
|
||||
src: url('./concertone-regular.ttf');
|
||||
|
@ -30,16 +52,19 @@ circle.erfa, circle.chaostreff {
|
|||
text.erfalabel {
|
||||
font-family: concertone;
|
||||
font-size: 45px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
rect.debugleft {
|
||||
stroke: red;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
rect.debugright {
|
||||
stroke: green;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue