tangram-airports 0.2.1__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,113 +1,68 @@
1
1
  <template>
2
- <div class="airport-search">
3
- <input
4
- v-model="query"
5
- type="text"
6
- placeholder="Search for airports..."
7
- @click="($event.target as HTMLInputElement).select()"
8
- @input="onInput"
9
- />
10
- <ul v-if="results.length" class="search-results">
11
- <li
12
- v-for="airport in results"
13
- :key="airport.icao"
14
- @click="selectAirport(airport)"
15
- >
16
- {{ airport.name }} ({{ airport.iata }} | {{ airport.icao }})
17
- </li>
18
- </ul>
2
+ <div class="airport-result">
3
+ <div class="row">
4
+ <span class="name">
5
+ <HighlightText :text="name" :query="query" />
6
+ </span>
7
+ <div class="chips">
8
+ <span class="chip blue">
9
+ <HighlightText :text="iata" :query="query" />
10
+ </span>
11
+ <span class="chip yellow">
12
+ <HighlightText :text="icao" :query="query" />
13
+ </span>
14
+ </div>
15
+ </div>
16
+ <div class="subtitle">
17
+ <HighlightText :text="city" :query="query" />, {{ countryCode }}
18
+ </div>
19
19
  </div>
20
20
  </template>
21
21
 
22
22
  <script setup lang="ts">
23
- import { ref, inject } from "vue";
24
- import type { TangramApi } from "@open-aviation/tangram-core/api";
25
- import { airport_information } from "rs1090-wasm";
23
+ import { HighlightText } from "@open-aviation/tangram-core/components";
26
24
 
27
- interface Airport {
28
- lat: number;
29
- lon: number;
25
+ defineProps<{
30
26
  name: string;
27
+ city: string;
28
+ countryCode: string;
31
29
  iata: string;
32
30
  icao: string;
33
- }
34
-
35
- const tangramApi = inject<TangramApi>("tangramApi");
36
- if (!tangramApi) {
37
- throw new Error("assert: tangram api not provided");
38
- }
39
- const query = ref("");
40
- const results = ref<Airport[]>([]);
41
- const timeoutId = ref<number | null>(null);
42
-
43
- const onInput = () => {
44
- if (timeoutId.value) {
45
- clearTimeout(timeoutId.value);
46
- }
47
- if (query.value.length >= 3) {
48
- timeoutId.value = window.setTimeout(() => {
49
- searchAirports();
50
- }, 300);
51
- } else {
52
- results.value = [];
53
- }
54
- };
55
-
56
- const searchAirports = () => {
57
- results.value = airport_information(query.value);
58
- };
59
-
60
- const selectAirport = (airport: Airport) => {
61
- tangramApi.map.getMapInstance().flyTo({
62
- center: [airport.lon, airport.lat],
63
- zoom: 13,
64
- speed: 1.2
65
- });
66
- query.value = "";
67
- results.value = [];
68
- };
31
+ query: string;
32
+ }>();
69
33
  </script>
70
34
 
71
35
  <style scoped>
72
- .airport-search {
73
- position: absolute;
74
- width: 300px;
75
- z-index: 1000;
76
- top: 10px;
77
- right: 10px;
36
+ .row {
37
+ display: flex;
38
+ justify-content: space-between;
39
+ align-items: center;
40
+ color: var(--t-fg);
78
41
  }
79
-
80
- .airport-search input {
81
- width: 100%;
82
- padding: 8px 12px;
83
- border: 1px solid #ccc;
84
- border-radius: 10px;
85
- font-family: "B612", sans-serif;
86
- box-sizing: border-box;
42
+ .name {
43
+ font-weight: 500;
44
+ font-size: 14px;
87
45
  }
88
-
89
- .search-results {
90
- position: absolute;
91
- top: 100%;
92
- left: 0;
93
- right: 0;
94
- padding: 0;
95
- margin: 4px 0 0 0;
96
- list-style: none;
97
- background: #fff;
98
- border: 1px solid #ccc;
99
- z-index: 1001;
100
- max-height: 200px;
101
- overflow-y: auto;
102
- font-family: "B612", sans-serif;
46
+ .subtitle {
47
+ font-size: 12px;
48
+ color: var(--t-muted);
103
49
  }
104
-
105
- .search-results li {
106
- padding: 5px 10px;
107
- cursor: pointer;
50
+ .chips {
51
+ display: flex;
52
+ gap: 4px;
108
53
  }
109
-
110
- .search-results li:hover {
111
- background-color: #eee;
54
+ .chip {
55
+ border-radius: 4px;
56
+ padding: 0 4px;
57
+ font-family: monospace;
58
+ font-size: 11px;
59
+ }
60
+ .blue {
61
+ background: var(--t-accent1);
62
+ color: var(--t-accent1-fg);
63
+ }
64
+ .yellow {
65
+ background: var(--t-accent2);
66
+ color: var(--t-accent2-fg);
112
67
  }
113
68
  </style>
@@ -1 +1 @@
1
- .airport-search[data-v-ddbda8e0]{position:absolute;width:300px;z-index:1000;top:10px;right:10px}.airport-search input[data-v-ddbda8e0]{width:100%;padding:8px 12px;border:1px solid #ccc;border-radius:10px;font-family:B612,sans-serif;box-sizing:border-box}.search-results[data-v-ddbda8e0]{position:absolute;top:100%;left:0;right:0;padding:0;margin:4px 0 0;list-style:none;background:#fff;border:1px solid #ccc;z-index:1001;max-height:200px;overflow-y:auto;font-family:B612,sans-serif}.search-results li[data-v-ddbda8e0]{padding:5px 10px;cursor:pointer}.search-results li[data-v-ddbda8e0]:hover{background-color:#eee}
1
+ .highlight[data-v-da0b39b4]{font-weight:800;background:#ff03;color:inherit}.row[data-v-a49e3fbb]{display:flex;justify-content:space-between;align-items:center;color:var(--t-fg)}.name[data-v-a49e3fbb]{font-weight:500;font-size:14px}.subtitle[data-v-a49e3fbb]{font-size:12px;color:var(--t-muted)}.chips[data-v-a49e3fbb]{display:flex;gap:4px}.chip[data-v-a49e3fbb]{border-radius:4px;padding:0 4px;font-family:monospace;font-size:11px}.blue[data-v-a49e3fbb]{background:var(--t-accent1);color:var(--t-accent1-fg)}.yellow[data-v-a49e3fbb]{background:var(--t-accent2);color:var(--t-accent2-fg)}
@@ -1,55 +1,99 @@
1
- import { defineComponent as _, inject as g, ref as u, createElementBlock as s, openBlock as i, withDirectives as f, createCommentVNode as h, createElementVNode as k, vModelText as y, Fragment as w, renderList as A, toDisplayString as p } from "vue";
2
1
  import { airport_information as x } from "rs1090-wasm";
3
- const C = { class: "airport-search" }, I = {
4
- key: 0,
5
- class: "search-results"
6
- }, S = ["onClick"], T = /* @__PURE__ */ _({
2
+ import { defineComponent as p, computed as _, createElementBlock as u, openBlock as d, Fragment as g, renderList as f, normalizeClass as q, toDisplayString as y, createElementVNode as c, createVNode as a, unref as i, createTextVNode as v } from "vue";
3
+ const C = /* @__PURE__ */ p({
4
+ __name: "HighlightText",
5
+ props: {
6
+ text: {},
7
+ query: {}
8
+ },
9
+ setup(e) {
10
+ const r = e, o = _(() => {
11
+ if (!r.query || !r.text) return [{ t: r.text, m: !1 }];
12
+ const s = r.query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), t = new RegExp(`(${s})`, "gi");
13
+ return r.text.split(t).map((n) => ({ t: n, m: n.toLowerCase() === r.query.toLowerCase() })).filter((n) => n.t);
14
+ });
15
+ return (s, t) => (d(), u("span", null, [
16
+ (d(!0), u(g, null, f(o.value, (n, h) => (d(), u("span", {
17
+ key: h,
18
+ class: q({ highlight: n.m })
19
+ }, y(n.t), 3))), 128))
20
+ ]));
21
+ }
22
+ }), m = (e, r) => {
23
+ const o = e.__vccOpts || e;
24
+ for (const [s, t] of r)
25
+ o[s] = t;
26
+ return o;
27
+ }, l = /* @__PURE__ */ m(C, [["__scopeId", "data-v-da0b39b4"]]), b = { class: "airport-result" }, w = { class: "row" }, $ = { class: "name" }, k = { class: "chips" }, S = { class: "chip blue" }, T = { class: "chip yellow" }, A = { class: "subtitle" }, E = /* @__PURE__ */ p({
7
28
  __name: "AirportSearchWidget",
8
- setup(r) {
9
- const a = g("tangramApi");
10
- if (!a)
11
- throw new Error("assert: tangram api not provided");
12
- const t = u(""), o = u([]), n = u(null), d = () => {
13
- n.value && clearTimeout(n.value), t.value.length >= 3 ? n.value = window.setTimeout(() => {
14
- m();
15
- }, 300) : o.value = [];
16
- }, m = () => {
17
- o.value = x(t.value);
18
- }, v = (c) => {
19
- a.map.getMapInstance().flyTo({
20
- center: [c.lon, c.lat],
21
- zoom: 13,
22
- speed: 1.2
23
- }), t.value = "", o.value = [];
24
- };
25
- return (c, l) => (i(), s("div", C, [
26
- f(k("input", {
27
- "onUpdate:modelValue": l[0] || (l[0] = (e) => t.value = e),
28
- type: "text",
29
- placeholder: "Search for airports...",
30
- onClick: l[1] || (l[1] = (e) => e.target.select()),
31
- onInput: d
32
- }, null, 544), [
33
- [y, t.value]
29
+ props: {
30
+ name: {},
31
+ city: {},
32
+ countryCode: {},
33
+ iata: {},
34
+ icao: {},
35
+ query: {}
36
+ },
37
+ setup(e) {
38
+ return (r, o) => (d(), u("div", b, [
39
+ c("div", w, [
40
+ c("span", $, [
41
+ a(i(l), {
42
+ text: e.name,
43
+ query: e.query
44
+ }, null, 8, ["text", "query"])
45
+ ]),
46
+ c("div", k, [
47
+ c("span", S, [
48
+ a(i(l), {
49
+ text: e.iata,
50
+ query: e.query
51
+ }, null, 8, ["text", "query"])
52
+ ]),
53
+ c("span", T, [
54
+ a(i(l), {
55
+ text: e.icao,
56
+ query: e.query
57
+ }, null, 8, ["text", "query"])
58
+ ])
59
+ ])
34
60
  ]),
35
- o.value.length ? (i(), s("ul", I, [
36
- (i(!0), s(w, null, A(o.value, (e) => (i(), s("li", {
37
- key: e.icao,
38
- onClick: (V) => v(e)
39
- }, p(e.name) + " (" + p(e.iata) + " | " + p(e.icao) + ") ", 9, S))), 128))
40
- ])) : h("", !0)
61
+ c("div", A, [
62
+ a(i(l), {
63
+ text: e.city,
64
+ query: e.query
65
+ }, null, 8, ["text", "query"]),
66
+ v(", " + y(e.countryCode), 1)
67
+ ])
41
68
  ]));
42
69
  }
43
- }), E = (r, a) => {
44
- const t = r.__vccOpts || r;
45
- for (const [o, n] of a)
46
- t[o] = n;
47
- return t;
48
- }, M = /* @__PURE__ */ E(T, [["__scopeId", "data-v-ddbda8e0"]]);
49
- function D(r) {
50
- r.ui.registerWidget("airport-search-widget", "MapOverlay", M);
70
+ }), I = /* @__PURE__ */ m(E, [["__scopeId", "data-v-a49e3fbb"]]);
71
+ function V(e) {
72
+ e.search.registerProvider({
73
+ id: "airports",
74
+ name: "Airports",
75
+ search: async (r, o) => r.length < 3 || o.aborted ? [] : x(r).slice(0, 10).map((t) => ({
76
+ id: `airport-${t.icao}`,
77
+ component: I,
78
+ props: {
79
+ name: t.name,
80
+ city: t.city,
81
+ countryCode: t.countryCode,
82
+ iata: t.iata,
83
+ icao: t.icao
84
+ },
85
+ score: 100,
86
+ onSelect: () => {
87
+ e.map.getMapInstance().flyTo({
88
+ center: [t.lon, t.lat],
89
+ zoom: 13,
90
+ speed: 1.2
91
+ });
92
+ }
93
+ }))
94
+ });
51
95
  }
52
96
  export {
53
- D as install
97
+ V as install
54
98
  };
55
99
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/tangram_airports/AirportSearchWidget.vue","../src/tangram_airports/index.ts"],"sourcesContent":["<template>\n <div class=\"airport-search\">\n <input\n v-model=\"query\"\n type=\"text\"\n placeholder=\"Search for airports...\"\n @click=\"($event.target as HTMLInputElement).select()\"\n @input=\"onInput\"\n />\n <ul v-if=\"results.length\" class=\"search-results\">\n <li\n v-for=\"airport in results\"\n :key=\"airport.icao\"\n @click=\"selectAirport(airport)\"\n >\n {{ airport.name }} ({{ airport.iata }} | {{ airport.icao }})\n </li>\n </ul>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, inject } from \"vue\";\nimport type { TangramApi } from \"@open-aviation/tangram-core/api\";\nimport { airport_information } from \"rs1090-wasm\";\n\ninterface Airport {\n lat: number;\n lon: number;\n name: string;\n iata: string;\n icao: string;\n}\n\nconst tangramApi = inject<TangramApi>(\"tangramApi\");\nif (!tangramApi) {\n throw new Error(\"assert: tangram api not provided\");\n}\nconst query = ref(\"\");\nconst results = ref<Airport[]>([]);\nconst timeoutId = ref<number | null>(null);\n\nconst onInput = () => {\n if (timeoutId.value) {\n clearTimeout(timeoutId.value);\n }\n if (query.value.length >= 3) {\n timeoutId.value = window.setTimeout(() => {\n searchAirports();\n }, 300);\n } else {\n results.value = [];\n }\n};\n\nconst searchAirports = () => {\n results.value = airport_information(query.value);\n};\n\nconst selectAirport = (airport: Airport) => {\n tangramApi.map.getMapInstance().flyTo({\n center: [airport.lon, airport.lat],\n zoom: 13,\n speed: 1.2\n });\n query.value = \"\";\n results.value = [];\n};\n</script>\n\n<style scoped>\n.airport-search {\n position: absolute;\n width: 300px;\n z-index: 1000;\n top: 10px;\n right: 10px;\n}\n\n.airport-search input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid #ccc;\n border-radius: 10px;\n font-family: \"B612\", sans-serif;\n box-sizing: border-box;\n}\n\n.search-results {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n padding: 0;\n margin: 4px 0 0 0;\n list-style: none;\n background: #fff;\n border: 1px solid #ccc;\n z-index: 1001;\n max-height: 200px;\n overflow-y: auto;\n font-family: \"B612\", sans-serif;\n}\n\n.search-results li {\n padding: 5px 10px;\n cursor: pointer;\n}\n\n.search-results li:hover {\n background-color: #eee;\n}\n</style>\n","import type { TangramApi } from \"@open-aviation/tangram-core/api\";\nimport AirportSearchWidget from \"./AirportSearchWidget.vue\";\n\nexport function install(api: TangramApi) {\n api.ui.registerWidget(\"airport-search-widget\", \"MapOverlay\", AirportSearchWidget);\n}\n"],"names":["tangramApi","inject","query","ref","results","timeoutId","onInput","searchAirports","airport_information","selectAirport","airport","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","$event","_cache","_hoisted_2","_Fragment","_renderList","_toDisplayString","_hoisted_3","install","api","AirportSearchWidget"],"mappings":";;;;;;;;AAkCA,UAAMA,IAAaC,EAAmB,YAAY;AAClD,QAAI,CAACD;AACH,YAAM,IAAI,MAAM,kCAAkC;AAEpD,UAAME,IAAQC,EAAI,EAAE,GACdC,IAAUD,EAAe,EAAE,GAC3BE,IAAYF,EAAmB,IAAI,GAEnCG,IAAU,MAAM;AACpB,MAAID,EAAU,SACZ,aAAaA,EAAU,KAAK,GAE1BH,EAAM,MAAM,UAAU,IACxBG,EAAU,QAAQ,OAAO,WAAW,MAAM;AACxC,QAAAE,EAAA;AAAA,MACF,GAAG,GAAG,IAENH,EAAQ,QAAQ,CAAA;AAAA,IAEpB,GAEMG,IAAiB,MAAM;AAC3B,MAAAH,EAAQ,QAAQI,EAAoBN,EAAM,KAAK;AAAA,IACjD,GAEMO,IAAgB,CAACC,MAAqB;AAC1C,MAAAV,EAAW,IAAI,eAAA,EAAiB,MAAM;AAAA,QACpC,QAAQ,CAACU,EAAQ,KAAKA,EAAQ,GAAG;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,MAAA,CACR,GACDR,EAAM,QAAQ,IACdE,EAAQ,QAAQ,CAAA;AAAA,IAClB;sBAlEEO,EAAA,GAAAC,EAiBM,OAjBNC,GAiBM;AAAA,QAhBJC,EAME,SAAA;AAAA,sDALSZ,EAAK,QAAAa;AAAA,QACd,MAAK;AAAA,QACL,aAAY;AAAA,QACX,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAD,MAAGA,EAAO,OAA4B,OAAA;AAAA,QAC3C,SAAAT;AAAA,MAAA;YAJQJ,EAAA,KAAK;AAAA,MAAA;MAMNE,EAAA,MAAQ,UAAlBO,KAAAC,EAQK,MARLK,GAQK;AAAA,gBAPHL,EAMKM,GAAA,MAAAC,EALef,EAAA,OAAO,CAAlBM,YADTE,EAMK,MAAA;AAAA,UAJF,KAAKF,EAAQ;AAAA,UACb,SAAK,CAAAK,MAAEN,EAAcC,CAAO;AAAA,QAAA,GAE1BU,EAAAV,EAAQ,IAAI,IAAG,SAAKA,EAAQ,IAAI,IAAG,QAAGU,EAAGV,EAAQ,IAAI,IAAG,MAC7D,GAAAW,CAAA;;;;;;;;;;ACbC,SAASC,EAAQC,GAAiB;AACvC,EAAAA,EAAI,GAAG,eAAe,yBAAyB,cAAcC,CAAmB;AAClF;"}
1
+ {"version":3,"file":"index.js","sources":["../../tangram_core/src/tangram_core/HighlightText.vue","../src/tangram_airports/AirportSearchWidget.vue","../src/tangram_airports/index.ts"],"sourcesContent":["<template>\n <span>\n <span v-for=\"(p, i) in parts\" :key=\"i\" :class=\"{ highlight: p.m }\">{{ p.t }}</span>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nconst props = defineProps<{\n text: string;\n query: string;\n}>();\n\nconst parts = computed(() => {\n if (!props.query || !props.text) return [{ t: props.text, m: false }];\n const escapedQuery = props.query.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const r = new RegExp(`(${escapedQuery})`, \"gi\");\n return props.text\n .split(r)\n .map(t => ({ t, m: t.toLowerCase() === props.query.toLowerCase() }))\n .filter(x => x.t);\n});\n</script>\n\n<style scoped>\n.highlight {\n font-weight: 800;\n background: rgba(255, 255, 0, 0.2);\n color: inherit;\n}\n</style>\n","<template>\n <div class=\"airport-result\">\n <div class=\"row\">\n <span class=\"name\">\n <HighlightText :text=\"name\" :query=\"query\" />\n </span>\n <div class=\"chips\">\n <span class=\"chip blue\">\n <HighlightText :text=\"iata\" :query=\"query\" />\n </span>\n <span class=\"chip yellow\">\n <HighlightText :text=\"icao\" :query=\"query\" />\n </span>\n </div>\n </div>\n <div class=\"subtitle\">\n <HighlightText :text=\"city\" :query=\"query\" />, {{ countryCode }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { HighlightText } from \"@open-aviation/tangram-core/components\";\n\ndefineProps<{\n name: string;\n city: string;\n countryCode: string;\n iata: string;\n icao: string;\n query: string;\n}>();\n</script>\n\n<style scoped>\n.row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--t-fg);\n}\n.name {\n font-weight: 500;\n font-size: 14px;\n}\n.subtitle {\n font-size: 12px;\n color: var(--t-muted);\n}\n.chips {\n display: flex;\n gap: 4px;\n}\n.chip {\n border-radius: 4px;\n padding: 0 4px;\n font-family: monospace;\n font-size: 11px;\n}\n.blue {\n background: var(--t-accent1);\n color: var(--t-accent1-fg);\n}\n.yellow {\n background: var(--t-accent2);\n color: var(--t-accent2-fg);\n}\n</style>\n","import type { TangramApi } from \"@open-aviation/tangram-core/api\";\nimport { airport_information } from \"rs1090-wasm\";\nimport AirportSearchWidget from \"./AirportSearchWidget.vue\";\n\nexport function install(api: TangramApi) {\n api.search.registerProvider({\n id: \"airports\",\n name: \"Airports\",\n search: async (query, signal) => {\n if (query.length < 3 || signal.aborted) return [];\n\n const airports = airport_information(query);\n return airports.slice(0, 10).map(a => ({\n id: `airport-${a.icao}`,\n component: AirportSearchWidget,\n props: {\n name: a.name,\n city: a.city,\n countryCode: a.countryCode,\n iata: a.iata,\n icao: a.icao\n },\n score: 100,\n onSelect: () => {\n api.map.getMapInstance().flyTo({\n center: [a.lon, a.lat],\n zoom: 13,\n speed: 1.2\n });\n }\n }));\n }\n });\n}\n"],"names":["props","__props","parts","computed","escapedQuery","r","t","x","_createElementBlock","_openBlock","_Fragment","_renderList","p","i","_normalizeClass","_toDisplayString","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","_unref","HighlightText","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_createTextVNode","install","api","query","signal","airport_information","a","AirportSearchWidget"],"mappings":";;;;;;;;;AASA,UAAMA,IAAQC,GAKRC,IAAQC,EAAS,MAAM;AAC3B,UAAI,CAACH,EAAM,SAAS,CAACA,EAAM,KAAM,QAAO,CAAC,EAAE,GAAGA,EAAM,MAAM,GAAG,IAAO;AACpE,YAAMI,IAAeJ,EAAM,MAAM,QAAQ,uBAAuB,MAAM,GAChEK,IAAI,IAAI,OAAO,IAAID,CAAY,KAAK,IAAI;AAC9C,aAAOJ,EAAM,KACV,MAAMK,CAAC,EACP,IAAI,CAAAC,OAAM,EAAE,GAAAA,GAAG,GAAGA,EAAE,kBAAkBN,EAAM,MAAM,cAAY,EAAI,EAClE,OAAO,CAAAO,MAAKA,EAAE,CAAC;AAAA,IACpB,CAAC;2BArBCC,EAEO,QAAA,MAAA;AAAA,OADLC,EAAA,EAAA,GAAAD,EAAmFE,GAAA,MAAAC,EAA5DT,EAAA,OAAK,CAAdU,GAAGC,YAAjBL,EAAmF,QAAA;AAAA,QAApD,KAAKK;AAAA,QAAI,OAAKC,EAAA,EAAA,WAAeF,EAAE,GAAC;AAAA,MAAA,GAAOG,EAAAH,EAAE,CAAC,GAAA,CAAA;;;;;;;;;;;;;;;;;;;sBCD3EH,EAAA,GAAAD,EAiBM,OAjBNQ,GAiBM;AAAA,MAhBJC,EAYM,OAZNC,GAYM;AAAA,QAXJD,EAEO,QAFPE,GAEO;AAAA,UADLC,EAA6CC,EAAAC,CAAA,GAAA;AAAA,YAA7B,MAAMrB,EAAA;AAAA,YAAO,OAAOA,EAAA;AAAA,UAAA;;QAEtCgB,EAOM,OAPNM,GAOM;AAAA,UANJN,EAEO,QAFPO,GAEO;AAAA,YADLJ,EAA6CC,EAAAC,CAAA,GAAA;AAAA,cAA7B,MAAMrB,EAAA;AAAA,cAAO,OAAOA,EAAA;AAAA,YAAA;;UAEtCgB,EAEO,QAFPQ,GAEO;AAAA,YADLL,EAA6CC,EAAAC,CAAA,GAAA;AAAA,cAA7B,MAAMrB,EAAA;AAAA,cAAO,OAAOA,EAAA;AAAA,YAAA;;;;MAI1CgB,EAEM,OAFNS,GAEM;AAAA,QADJN,EAA6CC,EAAAC,CAAA,GAAA;AAAA,UAA7B,MAAMrB,EAAA;AAAA,UAAO,OAAOA,EAAA;AAAA,QAAA;QAAS0B,EAAA,SAAK1B,EAAA,WAAW,GAAA,CAAA;AAAA,MAAA;;;;ACZ5D,SAAS2B,EAAQC,GAAiB;AACvC,EAAAA,EAAI,OAAO,iBAAiB;AAAA,IAC1B,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,OAAOC,GAAOC,MAChBD,EAAM,SAAS,KAAKC,EAAO,UAAgB,CAAA,IAE9BC,EAAoBF,CAAK,EAC1B,MAAM,GAAG,EAAE,EAAE,IAAI,CAAAG,OAAM;AAAA,MACrC,IAAI,WAAWA,EAAE,IAAI;AAAA,MACrB,WAAWC;AAAA,MACX,OAAO;AAAA,QACL,MAAMD,EAAE;AAAA,QACR,MAAMA,EAAE;AAAA,QACR,aAAaA,EAAE;AAAA,QACf,MAAMA,EAAE;AAAA,QACR,MAAMA,EAAE;AAAA,MAAA;AAAA,MAEV,OAAO;AAAA,MACP,UAAU,MAAM;AACd,QAAAJ,EAAI,IAAI,eAAA,EAAiB,MAAM;AAAA,UAC7B,QAAQ,CAACI,EAAE,KAAKA,EAAE,GAAG;AAAA,UACrB,MAAM;AAAA,UACN,OAAO;AAAA,QAAA,CACR;AAAA,MACH;AAAA,IAAA,EACA;AAAA,EACJ,CACD;AACH;"}
tangram_airports/index.ts CHANGED
@@ -1,6 +1,34 @@
1
1
  import type { TangramApi } from "@open-aviation/tangram-core/api";
2
+ import { airport_information } from "rs1090-wasm";
2
3
  import AirportSearchWidget from "./AirportSearchWidget.vue";
3
4
 
4
5
  export function install(api: TangramApi) {
5
- api.ui.registerWidget("airport-search-widget", "MapOverlay", AirportSearchWidget);
6
+ api.search.registerProvider({
7
+ id: "airports",
8
+ name: "Airports",
9
+ search: async (query, signal) => {
10
+ if (query.length < 3 || signal.aborted) return [];
11
+
12
+ const airports = airport_information(query);
13
+ return airports.slice(0, 10).map(a => ({
14
+ id: `airport-${a.icao}`,
15
+ component: AirportSearchWidget,
16
+ props: {
17
+ name: a.name,
18
+ city: a.city,
19
+ countryCode: a.countryCode,
20
+ iata: a.iata,
21
+ icao: a.icao
22
+ },
23
+ score: 100,
24
+ onSelect: () => {
25
+ api.map.getMapInstance().flyTo({
26
+ center: [a.lon, a.lat],
27
+ zoom: 13,
28
+ speed: 1.2
29
+ });
30
+ }
31
+ }));
32
+ }
33
+ });
6
34
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-aviation/tangram-airports",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "main": "src/tangram_airports/index.ts",
@@ -12,6 +12,6 @@
12
12
  },
13
13
  "devDependencies": {
14
14
  "rs1090-wasm": "^0.4.14",
15
- "vue": "^3.5.25"
15
+ "vue": "^3.5.27"
16
16
  }
17
17
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tangram_airports
3
- Version: 0.2.1
3
+ Version: 0.4.0
4
4
  Summary: Airport search widget plugin for tangram
5
5
  Author-email: Xavier Olive <git@xoolive.org>
6
6
  License-Expression: AGPL-3.0
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
15
15
  Classifier: Programming Language :: Python :: 3.14
16
16
  Classifier: Topic :: Scientific/Engineering :: Visualization
17
17
  Requires-Python: >=3.10
18
- Requires-Dist: tangram-core>=0.2.0
18
+ Requires-Dist: tangram-core>=0.2.1
19
19
  Description-Content-Type: text/markdown
20
20
 
21
21
  # tangram_airports
@@ -0,0 +1,12 @@
1
+ tangram_airports/AirportSearchWidget.vue,sha256=Q7ntdSFL9501k4Ka9yIacBuabmd3njjXvyYUCgrNLxo,1301
2
+ tangram_airports/__init__.py,sha256=Ac5Xf05VZmfh5ojtmmve3csrvPrqzWXJ5LA1Z5KMnJE,88
3
+ tangram_airports/index.ts,sha256=HJmwsO6eDz2TfKq0FcmqDqncYoVNAlj6qn9DFm4UwPY,945
4
+ tangram_airports/dist-frontend/index.css,sha256=A6kfPMPes6aFek9fawaoDJ1c9FoYbxZVD_jkHbRbcSU,588
5
+ tangram_airports/dist-frontend/index.js,sha256=zLfMbAYPMMhZG4WJspxY_xIKegfUcYW3WEqFKbl4_UY,2931
6
+ tangram_airports/dist-frontend/index.js.map,sha256=b_bK7weqnnkEuP0_QLC5cZjTqOUAX5DdzokmOheUHtM,5659
7
+ tangram_airports/dist-frontend/plugin.json,sha256=HddNVWbOpTk0UFtbUy8frAjbz1Rw_kiRNxppZJcfi6k,93
8
+ tangram_airports/package.json,sha256=xdWb-aC2bYrEtA35Hn6q8Hq0zXBbKKhpFAUzz205IkU,350
9
+ tangram_airports-0.4.0.dist-info/METADATA,sha256=_LIGBh1l_Y-Zo1zZTDRVMlBnFc13EZ_9ZoJcDk29uFE,1428
10
+ tangram_airports-0.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
11
+ tangram_airports-0.4.0.dist-info/entry_points.txt,sha256=x_brdPCglCJL2UVVRCg-AIyAfdNpnV3k-v2XE8xNOc8,66
12
+ tangram_airports-0.4.0.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- tangram_airports/AirportSearchWidget.vue,sha256=nla7RtdjscjlCv0hDUOlo6C0MYSVxYvBwdQjwm6cuPE,2275
2
- tangram_airports/__init__.py,sha256=Ac5Xf05VZmfh5ojtmmve3csrvPrqzWXJ5LA1Z5KMnJE,88
3
- tangram_airports/index.ts,sha256=d7zWrEeu_O4Fiy7ta0hdnnSKJho5zI1I2dRzPPmjm0s,259
4
- tangram_airports/dist-frontend/index.css,sha256=G8xBDgzxLQtPwzaaPIW_qvHIrtsx8VyecH8DgoQk5pg,615
5
- tangram_airports/dist-frontend/index.js,sha256=XYXCHhYI1DAfQcMVJr-gSPivGORszQcC60pHx0F-BiM,1913
6
- tangram_airports/dist-frontend/index.js.map,sha256=Vnuw94mpPVf1w-QS7TtdMRWqPfWtX4pGle-6krN01Z4,4410
7
- tangram_airports/dist-frontend/plugin.json,sha256=HddNVWbOpTk0UFtbUy8frAjbz1Rw_kiRNxppZJcfi6k,93
8
- tangram_airports/package.json,sha256=P2_3AqFQ4-OJv5-Okg7Jc04MSifxWPYOdNsxlXXl4rk,350
9
- tangram_airports-0.2.1.dist-info/METADATA,sha256=S5qPtW0ltDvM-Ofd6cckGP2qdvpeblFJ4h8oR7PLL4k,1428
10
- tangram_airports-0.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
11
- tangram_airports-0.2.1.dist-info/entry_points.txt,sha256=x_brdPCglCJL2UVVRCg-AIyAfdNpnV3k-v2XE8xNOc8,66
12
- tangram_airports-0.2.1.dist-info/RECORD,,