1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00

Wikibase: Reproduce geocoordinate logic of en.w:Module:Wd [#792]

This commit is contained in:
gnosygnu 2020-09-07 17:28:20 -04:00
parent 5f2e9c7514
commit de841f8ff2
2 changed files with 145 additions and 82 deletions

View File

@ -23,15 +23,16 @@ import gplx.Bry_find_;
import gplx.Byte_ascii; import gplx.Byte_ascii;
import gplx.Decimal_adp; import gplx.Decimal_adp;
import gplx.Decimal_adp_; import gplx.Decimal_adp_;
import gplx.Double_;
import gplx.Err_; import gplx.Err_;
import gplx.Gfo_usr_dlg_; import gplx.Gfo_usr_dlg_;
import gplx.Math_; import gplx.Math_;
import gplx.Object_;
import gplx.String_; import gplx.String_;
import gplx.core.brys.fmtrs.Bry_fmtr; import gplx.core.brys.fmtrs.Bry_fmtr;
import gplx.xowa.Xoae_app; import gplx.xowa.Xoae_app;
import gplx.xowa.langs.Xol_lang_itm; import gplx.xowa.langs.Xol_lang_itm;
import gplx.xowa.langs.Xol_lang_itm_; import gplx.xowa.langs.Xol_lang_itm_;
import gplx.xowa.xtns.mapSources.Map_dd2dms_func;
import gplx.xowa.xtns.wbases.claims.Wbase_claim_visitor; import gplx.xowa.xtns.wbases.claims.Wbase_claim_visitor;
import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_entity; import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_entity;
import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_globecoordinate; import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_globecoordinate;
@ -182,21 +183,45 @@ public class Wdata_prop_val_visitor implements Wbase_claim_visitor { // THREAD.U
} }
public void Visit_globecoordinate(Wbase_claim_globecoordinate itm) {Write_geo(Bool_.N, bfr, wdata_mgr.Hwtr_mgr().Lbl_mgr(), msgs, itm.Lat(), itm.Lng(), itm.Alt(), itm.Prc(), itm.Glb());} public void Visit_globecoordinate(Wbase_claim_globecoordinate itm) {Write_geo(Bool_.N, bfr, wdata_mgr.Hwtr_mgr().Lbl_mgr(), msgs, itm.Lat(), itm.Lng(), itm.Alt(), itm.Prc(), itm.Glb());}
public static void Write_geo(boolean wikidata_page, Bry_bfr bfr, Wdata_lbl_mgr lbl_mgr, Wdata_hwtr_msgs msgs, byte[] lat, byte[] lng, byte[] alt, byte[] prc, byte[] glb) { public static void Write_geo(boolean wikidata_page, Bry_bfr bfr, Wdata_lbl_mgr lbl_mgr, Wdata_hwtr_msgs msgs, byte[] lat, byte[] lng, byte[] alt, byte[] prc, byte[] glb) {
// get precision // 2020-09-06|ISSUE#:792|rewrite based on https://en.wikipedia.org/w/index.php?title=Module:Wd&action=edit; REF.MW: https://github.com/DataValues/Geo/blob/master/src/Formatters/LatLongFormatter.php
int precision_int = -1; // normalize precision
if (Bry_.Eq(prc, Object_.Bry__null) || Bry_.Eq(prc, Byte_ascii.Num_0_bry)) // "null" or "0" should be 1; PAGE:ru.w:Лысково_(Калужская_область) DATE:2016-11-24 double precision = Double_.parse_or(String_.new_a7(prc), Double_.NaN);
precision_int = 1; if (Double_.IsNaN(precision) || precision <= 0) { // "null" or "0" should be 1; PAGE:ru.w:Лысково_(Калужская_область) DATE:2016-11-24
else { precision = PRECISION_1_OVER_3600;
Decimal_adp precision_frac = Decimal_adp_.parse(String_.new_a7(prc));
precision_int = Math_.Log10(Decimal_adp_.One.Divide(precision_frac).To_int()); // convert precision to log10 integer; EX: .00027777 -> 3600 -> 3
} }
// build String double latitude = Double_.parse_or(String_.new_a7(lat), Double_.NaN);
gplx.xowa.xtns.mapSources.Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.N, lat, precision_int); double longitude = Double_.parse_or(String_.new_a7(lng), Double_.NaN);
bfr.Add_byte_comma().Add_byte_space(); latitude = Math_.Floor(latitude / precision + 0.5) * precision;
gplx.xowa.xtns.mapSources.Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.Y, lng, precision_int); longitude = Math_.Floor(longitude / precision + 0.5) * precision;
// write globe if any if (precision >= 1 - (PRECISION_1_OVER_60) && precision < 1) {
precision = 1;
}
else if (precision >= (PRECISION_1_OVER_60) - (PRECISION_1_OVER_3600) && precision < PRECISION_1_OVER_60) {
precision = PRECISION_1_OVER_60;
}
int unitsPerDegree = 1;
if (precision >= 1) {
unitsPerDegree = 1;
}
else if (precision >= PRECISION_1_OVER_60) {
unitsPerDegree = 60;
}
else {
unitsPerDegree = 3600;
}
int numDigits = (int)Math_.Ceil(-Math.log10(((double)(unitsPerDegree) * precision)));
numDigits += 4; // +4 b/c Map_dd2dms_func.Deg_to_dms needs 4 places to evaluate MS while fracs are evaulated as numDigits
// write lat / lng
Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.N, Bry_.new_a7(Double_.To_str(latitude)), numDigits);
bfr.Add_byte_comma().Add_byte_space();
Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.Y, Bry_.new_a7(Double_.To_str(longitude)), numDigits);
// write globe
if (wikidata_page) { if (wikidata_page) {
byte[] glb_ttl = Wdata_lbl_itm.Extract_ttl(glb); byte[] glb_ttl = Wdata_lbl_itm.Extract_ttl(glb);
if (glb_ttl != null) { if (glb_ttl != null) {
@ -207,7 +232,11 @@ public class Wdata_prop_val_visitor implements Wbase_claim_visitor { // THREAD.U
} }
} }
} }
private static final double
PRECISION_1_OVER_3600 = 1d / 3600d
, PRECISION_1_OVER_60 = 1d / 60d
;
private static final byte[] Wikidata_url = Bry_.new_a7("http://www.wikidata.org/entity/"); private static final byte[] Wikidata_url = Bry_.new_a7("http://www.wikidata.org/entity/");
public void Visit_system(Wbase_claim_value itm) {} public void Visit_system(Wbase_claim_value itm) {}
} }

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,70 +13,104 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; package gplx.xowa.xtns.wbases;
import org.junit.*; import gplx.core.tests.*; import gplx.xowa.xtns.wbases.imports.*;
public class Wdata_wiki_mgr_tst { import gplx.Bry_;
private final Wdata_prop_val_visitor__fxt fxt = new Wdata_prop_val_visitor__fxt(); import gplx.Bry_bfr;
@Test public void Basic() { import gplx.Bry_bfr_;
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init(); import gplx.String_;
fxt.Init__docs__add(fxt.Wdoc("Q1") import gplx.core.tests.Gftest;
.Add_sitelink("enwiki", "Q1_en") import gplx.xowa.Xoa_ttl;
); import gplx.xowa.Xowe_wiki;
import gplx.xowa.xtns.wbases.hwtrs.Wdata_hwtr_msgs;
fxt.Test_link("Q1_en" , "Q1"); import gplx.xowa.xtns.wbases.hwtrs.Wdata_lbl_mgr;
fxt.Test_link("Q1_nil", null); import org.junit.Test;
}
@Test public void Case_sensitive() { // PURPOSE: wikidata lkp should be case_sensitive; a vs A DATE:2013-09-03 public class Wdata_wiki_mgr_tst {
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init(); private final Wdata_prop_val_visitor__fxt fxt = new Wdata_prop_val_visitor__fxt();
fxt.Init__docs__add(fxt.Wdoc("Q1") @Test public void Basic() {
.Add_sitelink("enwiki", "Q1_EN") Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
); fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_sitelink("enwiki", "Q1_en")
fxt.Test_link("Q1_EN", "Q1"); );
fxt.Test_link("q1_en", null);
} fxt.Test_link("Q1_en" , "Q1");
@Test public void Non_canonical_ns() { // PURPOSE: handle wikidata entries in non-canonical ns; EX:ukwikisource and Author; PAGE:uk.s:Автор:Богдан_Гаврилишин DATE:2014-07-23 fxt.Test_link("Q1_nil", null);
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init(); }
Xowe_wiki wiki = fxt.Wiki(); @Test public void Case_sensitive() { // PURPOSE: wikidata lkp should be case_sensitive; a vs A DATE:2013-09-03
wiki.Ns_mgr().Add_new(124, "Test_ns"); Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
fxt.Init__docs__add(fxt.Wdoc("Q1") fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_sitelink("enwiki", "Test_ns:Test_page") .Add_sitelink("enwiki", "Q1_EN")
); );
fxt.Test_link(Xoa_ttl.Parse(fxt.Wiki(), 124, Bry_.new_a7("Test_page")), "Q1"); // NOTE: wdata will save to "000" ns, b/c "124" ns is not canonical fxt.Test_link("Q1_EN", "Q1");
} fxt.Test_link("q1_en", null);
@Test public void Write_json_as_html() { }
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init(); @Test public void Non_canonical_ns() { // PURPOSE: handle wikidata entries in non-canonical ns; EX:ukwikisource and Author; PAGE:uk.s:Автор:Богдан_Гаврилишин DATE:2014-07-23
fxt.Test_write_json_as_html("{'a':'b','c':['d','e'],'f':{'g':'<h>'}}", String_.Concat_lines_nl_skip_last Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
( "<span id=\"xowa-wikidata-json\">" Xowe_wiki wiki = fxt.Wiki();
, "{ \"a\":\"b\"" wiki.Ns_mgr().Add_new(124, "Test_ns");
, ", \"c\":" fxt.Init__docs__add(fxt.Wdoc("Q1")
, " [ \"d\"" .Add_sitelink("enwiki", "Test_ns:Test_page")
, " , \"e\"" );
, " ]"
, ", \"f\":" fxt.Test_link(Xoa_ttl.Parse(fxt.Wiki(), 124, Bry_.new_a7("Test_page")), "Q1"); // NOTE: wdata will save to "000" ns, b/c "124" ns is not canonical
, " { \"g\":\"&lt;h&gt;\"" }
, " }" @Test public void Write_json_as_html() {
, "}" Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
, "</span>" fxt.Test_write_json_as_html("{'a':'b','c':['d','e'],'f':{'g':'<h>'}}", String_.Concat_lines_nl_skip_last
)); ( "<span id=\"xowa-wikidata-json\">"
} , "{ \"a\":\"b\""
@Test public void Normalize_for_decimal() { , ", \"c\":"
fxt.Test__normalize_for_decimal("1234" , "1234"); // basic , " [ \"d\""
fxt.Test__normalize_for_decimal("+1234" , "1234"); // plus , " , \"e\""
fxt.Test__normalize_for_decimal("1,234" , "1234"); // comma , " ]"
fxt.Test__normalize_for_decimal("+1,234" , "1234"); // both , ", \"f\":"
} , " { \"g\":\"&lt;h&gt;\""
@Test public void Write_quantity_null() { // handle missing lbound / ubound; DATE:2016-12-03 , " }"
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init(); , "}"
, "</span>"
Bry_bfr bfr = Bry_bfr_.New(); ));
Wdata_prop_val_visitor.Write_quantity(bfr, fxt.Wdata_mgr(), fxt.Wiki().Lang(), Bry_.new_a7("123"), null, null, null); }
Gftest.Eq__str("123", bfr.To_bry_and_clear()); @Test public void Normalize_for_decimal() {
} fxt.Test__normalize_for_decimal("1234" , "1234"); // basic
} fxt.Test__normalize_for_decimal("+1234" , "1234"); // plus
class Wdata_prop_val_visitor__fxt { fxt.Test__normalize_for_decimal("1,234" , "1234"); // comma
public void Test__normalize_for_decimal(String raw, String expd) { fxt.Test__normalize_for_decimal("+1,234" , "1234"); // both
Gftest.Eq__str(expd, Wdata_prop_val_visitor.Normalize_for_decimal(Bry_.new_u8(raw)), raw); }
} @Test public void Write_quantity_null() { // handle missing lbound / ubound; DATE:2016-12-03
} Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
Bry_bfr bfr = Bry_bfr_.New();
Wdata_prop_val_visitor.Write_quantity(bfr, fxt.Wdata_mgr(), fxt.Wiki().Lang(), Bry_.new_a7("123"), null, null, null);
Gftest.Eq__str("123", bfr.To_bry_and_clear());
}
@Test public void Geo() {
// null precision
fxt.TestGeo("39°57&#39;42&#34;N, 83°0&#39;7&#34;W", "39.96177", "-83.00196", "null");
// 1/60 precision
fxt.TestGeo("39°58&#39;0&#34;N, 83°0&#39;0&#34;W", "39.96177", "-83.00196", "0.0166666667");
// 1/3600 precision
fxt.TestGeo("39°57&#39;42&#34;N, 83°0&#39;7&#34;W", "39.96177", "-83.00196", "0.0002777778");
// 2020-09-06|ISSUE#:792|fails if 1 digit precision; EX: 42.4 instead of 42.37
fxt.TestGeo("39°57&#39;42.37&#34;N, 83°0&#39;7.06&#34;W", "39.96177", "-83.00196", "1.0e-5");
}
}
class Wdata_prop_val_visitor__fxt {
public void Test__normalize_for_decimal(String raw, String expd) {
Gftest.Eq__str(expd, Wdata_prop_val_visitor.Normalize_for_decimal(Bry_.new_u8(raw)), raw);
}
public void TestGeo(String expd, String lat, String lng, String prc) {TestGeo(expd, lat, lng, prc, null);}
public void TestGeo(String expd, String lat, String lng, String prc, String glb) {
boolean wikidata_page = glb != null;
Wdata_lbl_mgr lbl_mgr = new Wdata_lbl_mgr();
Wdata_hwtr_msgs msgs = Wdata_hwtr_msgs.new_en_();
Bry_bfr bfr = Bry_bfr_.New();
Wdata_prop_val_visitor.Write_geo(wikidata_page, bfr, lbl_mgr, msgs, Bry_.new_u8(lat), Bry_.new_u8(lng), null, Bry_.new_u8(prc), Bry_.new_u8_safe(glb));
Gftest.Eq__str(expd, bfr.To_str_and_clear());
}
}