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

staging
gnosygnu 4 years ago
parent 5f2e9c7514
commit de841f8ff2

@ -23,15 +23,16 @@ import gplx.Bry_find_;
import gplx.Byte_ascii;
import gplx.Decimal_adp;
import gplx.Decimal_adp_;
import gplx.Double_;
import gplx.Err_;
import gplx.Gfo_usr_dlg_;
import gplx.Math_;
import gplx.Object_;
import gplx.String_;
import gplx.core.brys.fmtrs.Bry_fmtr;
import gplx.xowa.Xoae_app;
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.itms.Wbase_claim_entity;
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 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
int precision_int = -1;
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
precision_int = 1;
// 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
// normalize precision
double precision = Double_.parse_or(String_.new_a7(prc), Double_.NaN);
if (Double_.IsNaN(precision) || precision <= 0) { // "null" or "0" should be 1; PAGE:ru.w:Лысково_(Калужская_область) DATE:2016-11-24
precision = PRECISION_1_OVER_3600;
}
double latitude = Double_.parse_or(String_.new_a7(lat), Double_.NaN);
double longitude = Double_.parse_or(String_.new_a7(lng), Double_.NaN);
latitude = Math_.Floor(latitude / precision + 0.5) * precision;
longitude = Math_.Floor(longitude / precision + 0.5) * precision;
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 {
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
unitsPerDegree = 3600;
}
// build String
gplx.xowa.xtns.mapSources.Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.N, lat, precision_int);
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();
gplx.xowa.xtns.mapSources.Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.Y, lng, precision_int);
Map_dd2dms_func.Deg_to_dms(bfr, Bool_.Y, Bool_.Y, Bry_.new_a7(Double_.To_str(longitude)), numDigits);
// write globe if any
// write globe
if (wikidata_page) {
byte[] glb_ttl = Wdata_lbl_itm.Extract_ttl(glb);
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) {}
}

@ -1,6 +1,6 @@
/*
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,
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
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.*;
import org.junit.*; import gplx.core.tests.*; import gplx.xowa.xtns.wbases.imports.*;
public class Wdata_wiki_mgr_tst {
private final Wdata_prop_val_visitor__fxt fxt = new Wdata_prop_val_visitor__fxt();
@Test public void Basic() {
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_nil", null);
}
@Test public void Case_sensitive() { // PURPOSE: wikidata lkp should be case_sensitive; a vs A DATE:2013-09-03
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);
}
@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
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
Xowe_wiki wiki = fxt.Wiki();
wiki.Ns_mgr().Add_new(124, "Test_ns");
fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_sitelink("enwiki", "Test_ns:Test_page")
);
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
}
@Test public void Write_json_as_html() {
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
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\""
, ", \"c\":"
, " [ \"d\""
, " , \"e\""
, " ]"
, ", \"f\":"
, " { \"g\":\"&lt;h&gt;\""
, " }"
, "}"
, "</span>"
));
}
@Test public void Normalize_for_decimal() {
fxt.Test__normalize_for_decimal("1234" , "1234"); // basic
fxt.Test__normalize_for_decimal("+1234" , "1234"); // plus
fxt.Test__normalize_for_decimal("1,234" , "1234"); // comma
fxt.Test__normalize_for_decimal("+1,234" , "1234"); // both
}
@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());
}
}
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);
}
}
package gplx.xowa.xtns.wbases;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.String_;
import gplx.core.tests.Gftest;
import gplx.xowa.Xoa_ttl;
import gplx.xowa.Xowe_wiki;
import gplx.xowa.xtns.wbases.hwtrs.Wdata_hwtr_msgs;
import gplx.xowa.xtns.wbases.hwtrs.Wdata_lbl_mgr;
import org.junit.Test;
public class Wdata_wiki_mgr_tst {
private final Wdata_prop_val_visitor__fxt fxt = new Wdata_prop_val_visitor__fxt();
@Test public void Basic() {
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_nil", null);
}
@Test public void Case_sensitive() { // PURPOSE: wikidata lkp should be case_sensitive; a vs A DATE:2013-09-03
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);
}
@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
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
Xowe_wiki wiki = fxt.Wiki();
wiki.Ns_mgr().Add_new(124, "Test_ns");
fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_sitelink("enwiki", "Test_ns:Test_page")
);
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
}
@Test public void Write_json_as_html() {
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
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\""
, ", \"c\":"
, " [ \"d\""
, " , \"e\""
, " ]"
, ", \"f\":"
, " { \"g\":\"&lt;h&gt;\""
, " }"
, "}"
, "</span>"
));
}
@Test public void Normalize_for_decimal() {
fxt.Test__normalize_for_decimal("1234" , "1234"); // basic
fxt.Test__normalize_for_decimal("+1234" , "1234"); // plus
fxt.Test__normalize_for_decimal("1,234" , "1234"); // comma
fxt.Test__normalize_for_decimal("+1,234" , "1234"); // both
}
@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());
}
}

Loading…
Cancel
Save