From 5c3d6a173b3ef7ca3efcf44d186445247e162720 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Fri, 25 Sep 2020 08:42:52 -0400 Subject: [PATCH] Wikibase: Calc precision by using longitude when precision is null [#792] --- .../libs/Scrib_lib_wikibase_srl_visitor.java | 209 +++++++++++------- .../Scrib_lib_wikibase_srl_visitor_tst.java | 24 +- .../itms/Wbase_claim_globecoordinate.java | 8 - 3 files changed, 151 insertions(+), 90 deletions(-) diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor.java index 660a9fbcb..4992e6d52 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor.java @@ -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,82 +13,133 @@ 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.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*; -import gplx.xowa.xtns.wbases.core.*; import gplx.xowa.xtns.wbases.claims.*; import gplx.xowa.xtns.wbases.claims.enums.*; import gplx.xowa.xtns.wbases.claims.itms.*; -public class Scrib_lib_wikibase_srl_visitor implements Wbase_claim_visitor { - public Keyval[] Rv() {return rv;} Keyval[] rv; - public void Visit_str(Wbase_claim_string itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Reg.Get_str_or(itm.Val_tid(), Wbase_claim_type_.Itm__unknown.Key_str())); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, String_.new_u8(itm.Val_bry())); - } - public void Visit_entity(Wbase_claim_entity itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__entity.Key_str()); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Entity_value(itm)); - } - private static Keyval[] Entity_value(Wbase_claim_base itm) { - Wbase_claim_entity claim_entity = (Wbase_claim_entity)itm; - Keyval[] rv = new Keyval[3]; - rv[0] = Keyval_.new_(Wbase_claim_entity_.Itm__entity_type.Key_str(), claim_entity.Entity_tid_str()); - rv[1] = Keyval_.new_(Wbase_claim_entity_.Itm__numeric_id.Key_str(), claim_entity.Entity_id()); // NOTE: must be int, not String, else will fail when comparing directly to integer; PAGE:en.w:Hollywood_Walk_of_Fame DATE:2016-12-17 - rv[2] = Keyval_.new_(Wbase_claim_entity_.Itm__id.Key_str(), Wbase_claim_entity.To_xid__db(Wbase_claim_entity_.Itm__entity_type.Tid(), claim_entity.Entity_id_bry())); // "id" needed PAGE:es.w:Premio_Hugo_a_la_mejor_novela DATE:2017-09-04 - return rv; - } - public void Visit_monolingualtext(Wbase_claim_monolingualtext itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__monolingualtext.Key_str()); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Monolingualtext_value(itm)); - } - private static Keyval[] Monolingualtext_value(Wbase_claim_monolingualtext itm) { - Keyval[] rv = new Keyval[2]; - rv[0] = Keyval_.new_(Wbase_claim_monolingualtext_.Itm__text.Key_str() , String_.new_u8(itm.Text())); - rv[1] = Keyval_.new_(Wbase_claim_monolingualtext_.Itm__language.Key_str() , String_.new_u8(itm.Lang())); - return rv; - } - public void Visit_quantity(Wbase_claim_quantity itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__quantity.Key_str()); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Quantity_value(itm)); - } - private static Keyval[] Quantity_value(Wbase_claim_quantity itm) { - Keyval[] rv = new Keyval[4]; - rv[0] = Keyval_.new_(Wbase_claim_quantity_.Itm__amount.Key_str() , itm.Amount_as_num().To_str()); // NOTE: must be num b/c Module code will directly do math calc on it; EX: "99" not "+99"; PAGE:eo.w:Mud�; DATE:2015-11-08 - rv[1] = Keyval_.new_(Wbase_claim_quantity_.Itm__unit.Key_str() , String_.new_u8(itm.Unit())); - rv[2] = Keyval_.new_(Wbase_claim_quantity_.Itm__upperbound.Key_str() , itm.Ubound_as_num().To_str()); - rv[3] = Keyval_.new_(Wbase_claim_quantity_.Itm__lowerbound.Key_str() , itm.Lbound_as_num().To_str()); - return rv; - } - public void Visit_time(Wbase_claim_time itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__time.Key_str()); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Time_value(itm)); - } - private static Keyval[] Time_value(Wbase_claim_time itm) { - Keyval[] rv = new Keyval[6]; - rv[0] = Keyval_.new_(Wbase_claim_time_.Itm__time.Key_str() , String_.new_a7(itm.Time())); - rv[1] = Keyval_.new_(Wbase_claim_time_.Itm__precision.Key_str() , itm.Precision_int()); // NOTE: must return int, not str; DATE:2014-02-18 - rv[2] = Keyval_.new_(Wbase_claim_time_.Itm__before.Key_str() , itm.Before_int()); - rv[3] = Keyval_.new_(Wbase_claim_time_.Itm__after.Key_str() , itm.After_int()); - rv[4] = Keyval_.new_(Wbase_claim_time_.Itm__timezone.Key_str() , Wbase_claim_time_.Dflt__timezone.Val_int()); // ASSUME: always 0 b/c UTC?; DATE:2015-09-21 - rv[5] = Keyval_.new_(Wbase_claim_time_.Itm__calendarmodel.Key_str() , Wbase_claim_time_.Dflt__calendarmodel.Val_str()); - return rv; - } - public void Visit_globecoordinate(Wbase_claim_globecoordinate itm) { - rv = new Keyval[2]; - rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__globecoordinate.Key_str()); - rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Globecoordinate_value(itm)); - } - private static Keyval[] Globecoordinate_value(Wbase_claim_globecoordinate itm) { - Keyval[] rv = new Keyval[5]; - rv[0] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__latitude.Key_str() , Double_.parse(String_.new_a7(itm.Lat()))); - rv[1] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__longitude.Key_str() , Double_.parse(String_.new_a7(itm.Lng()))); - rv[2] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__altitude.Key_str() , String_.new_u8(itm.Alt())); - rv[3] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__globe.Key_str() , String_.new_u8(itm.Glb())); - rv[4] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__precision.Key_str() , itm.Prc_as_num().To_double()); - return rv; - } - public void Visit_system(Wbase_claim_value itm) { - rv = Keyval_.Ary_empty; - } +package gplx.xowa.xtns.scribunto.libs; + +import gplx.Bry_; +import gplx.Decimal_adp; +import gplx.Decimal_adp_; +import gplx.Double_; +import gplx.Keyval; +import gplx.Keyval_; +import gplx.Object_; +import gplx.String_; +import gplx.xowa.xtns.wbases.claims.Wbase_claim_visitor; +import gplx.xowa.xtns.wbases.claims.enums.Wbase_claim_type_; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_base; +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_; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_monolingualtext; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_monolingualtext_; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_quantity; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_quantity_; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_string; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_time; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_time_; +import gplx.xowa.xtns.wbases.claims.itms.Wbase_claim_value; + +public class Scrib_lib_wikibase_srl_visitor implements Wbase_claim_visitor { + public Keyval[] Rv() {return rv;} Keyval[] rv; + public void Visit_str(Wbase_claim_string itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Reg.Get_str_or(itm.Val_tid(), Wbase_claim_type_.Itm__unknown.Key_str())); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, String_.new_u8(itm.Val_bry())); + } + public void Visit_entity(Wbase_claim_entity itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__entity.Key_str()); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Entity_value(itm)); + } + private static Keyval[] Entity_value(Wbase_claim_base itm) { + Wbase_claim_entity claim_entity = (Wbase_claim_entity)itm; + Keyval[] rv = new Keyval[3]; + rv[0] = Keyval_.new_(Wbase_claim_entity_.Itm__entity_type.Key_str(), claim_entity.Entity_tid_str()); + rv[1] = Keyval_.new_(Wbase_claim_entity_.Itm__numeric_id.Key_str(), claim_entity.Entity_id()); // NOTE: must be int, not String, else will fail when comparing directly to integer; PAGE:en.w:Hollywood_Walk_of_Fame DATE:2016-12-17 + rv[2] = Keyval_.new_(Wbase_claim_entity_.Itm__id.Key_str(), Wbase_claim_entity.To_xid__db(Wbase_claim_entity_.Itm__entity_type.Tid(), claim_entity.Entity_id_bry())); // "id" needed PAGE:es.w:Premio_Hugo_a_la_mejor_novela DATE:2017-09-04 + return rv; + } + public void Visit_monolingualtext(Wbase_claim_monolingualtext itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__monolingualtext.Key_str()); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Monolingualtext_value(itm)); + } + private static Keyval[] Monolingualtext_value(Wbase_claim_monolingualtext itm) { + Keyval[] rv = new Keyval[2]; + rv[0] = Keyval_.new_(Wbase_claim_monolingualtext_.Itm__text.Key_str() , String_.new_u8(itm.Text())); + rv[1] = Keyval_.new_(Wbase_claim_monolingualtext_.Itm__language.Key_str() , String_.new_u8(itm.Lang())); + return rv; + } + public void Visit_quantity(Wbase_claim_quantity itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__quantity.Key_str()); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Quantity_value(itm)); + } + private static Keyval[] Quantity_value(Wbase_claim_quantity itm) { + Keyval[] rv = new Keyval[4]; + rv[0] = Keyval_.new_(Wbase_claim_quantity_.Itm__amount.Key_str() , itm.Amount_as_num().To_str()); // NOTE: must be num b/c Module code will directly do math calc on it; EX: "99" not "+99"; PAGE:eo.w:Mud�; DATE:2015-11-08 + rv[1] = Keyval_.new_(Wbase_claim_quantity_.Itm__unit.Key_str() , String_.new_u8(itm.Unit())); + rv[2] = Keyval_.new_(Wbase_claim_quantity_.Itm__upperbound.Key_str() , itm.Ubound_as_num().To_str()); + rv[3] = Keyval_.new_(Wbase_claim_quantity_.Itm__lowerbound.Key_str() , itm.Lbound_as_num().To_str()); + return rv; + } + public void Visit_time(Wbase_claim_time itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__time.Key_str()); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Time_value(itm)); + } + private static Keyval[] Time_value(Wbase_claim_time itm) { + Keyval[] rv = new Keyval[6]; + rv[0] = Keyval_.new_(Wbase_claim_time_.Itm__time.Key_str() , String_.new_a7(itm.Time())); + rv[1] = Keyval_.new_(Wbase_claim_time_.Itm__precision.Key_str() , itm.Precision_int()); // NOTE: must return int, not str; DATE:2014-02-18 + rv[2] = Keyval_.new_(Wbase_claim_time_.Itm__before.Key_str() , itm.Before_int()); + rv[3] = Keyval_.new_(Wbase_claim_time_.Itm__after.Key_str() , itm.After_int()); + rv[4] = Keyval_.new_(Wbase_claim_time_.Itm__timezone.Key_str() , Wbase_claim_time_.Dflt__timezone.Val_int()); // ASSUME: always 0 b/c UTC?; DATE:2015-09-21 + rv[5] = Keyval_.new_(Wbase_claim_time_.Itm__calendarmodel.Key_str() , Wbase_claim_time_.Dflt__calendarmodel.Val_str()); + return rv; + } + public void Visit_globecoordinate(Wbase_claim_globecoordinate itm) { + rv = new Keyval[2]; + rv[0] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_type, Wbase_claim_type_.Itm__globecoordinate.Key_str()); + rv[1] = Keyval_.new_(Scrib_lib_wikibase_srl.Key_value, Globecoordinate_value(itm)); + } + private static Keyval[] Globecoordinate_value(Wbase_claim_globecoordinate itm) { + Keyval[] rv = new Keyval[5]; + rv[0] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__latitude.Key_str() , Double_.parse(String_.new_a7(itm.Lat()))); + rv[1] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__longitude.Key_str() , Double_.parse(String_.new_a7(itm.Lng()))); + rv[2] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__altitude.Key_str() , String_.new_u8(itm.Alt())); + rv[3] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__globe.Key_str() , String_.new_u8(itm.Glb())); + rv[4] = Keyval_.new_(Wbase_claim_globecoordinate_.Itm__precision.Key_str() , CalcPrecision(itm.Prc(), itm.Lng()).To_double()); + return rv; + } + public void Visit_system(Wbase_claim_value itm) { + rv = Keyval_.Ary_empty; + } + public static Decimal_adp CalcPrecision(byte[] prc, byte[] lng) { + Decimal_adp rv; + + // precision is "null" + if (Bry_.Eq(prc, Object_.Bry__null)) { + // 2020-09-25|ISSUE#:792|use longitude to determine precision (contributed by desb42@) + int lngLen = lng.length; + int power = 0; + // calc power by finding decimal point + for (int i = 0; i < lngLen; i++) { + byte b = lng[i]; + if (b == '.') { + power = lngLen - (i + 1); // +1 to set after "." + if (power > 8) { // ensure power is 8 or less + power = 8; + } + break; + } + } + + rv = Decimal_adp_.float_((float)Math.pow(10, -power)); + } + else { + rv = Decimal_adp_.parse(String_.new_a7(prc)); + } + return rv; + } } \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor_tst.java index 2d9e60de6..1516a9f06 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl_visitor_tst.java @@ -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. @@ -16,6 +16,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt package gplx.xowa.xtns.scribunto.libs; import gplx.Bry_; +import gplx.Decimal_adp; import gplx.Double_; import gplx.Keyval; import gplx.core.tests.Gftest; @@ -25,10 +26,23 @@ import org.junit.Test; public class Scrib_lib_wikibase_srl_visitor_tst { private final Scrib_lib_wikibase_srl_visitor_fxt fxt = new Scrib_lib_wikibase_srl_visitor_fxt(); - @Test - public void Geo_null_precision() { + @Test public void Geo_null_precision() { fxt.TestGeoPrecision(0, "null"); // 2020-09-03|ISSUE#:792|null precision should default to 0 not 1;PAGE:wd:Q168751 } + @Test public void CalcPrecision() { + // 2020-09-25|ISSUE#:792|use longitude to determine precision (contributed by desb42@) + // precision is non-null -> use it + fxt.TestCalcPrecision("2.8E-4", "0.0002777777777777778", "-76.62027777777777"); + + // precision is null -> precision is number of decimal points + fxt.TestCalcPrecision("1.0E-4", "null", "-76.1234"); + + // precision is null -> precision is number of decimal points but max is 8 + fxt.TestCalcPrecision("1.0E-8", "null", "-76.62027777777777"); + + // precision is null -> precision is 1 + fxt.TestCalcPrecision("1.0E0", "null", "12"); + } } class Scrib_lib_wikibase_srl_visitor_fxt { private final Scrib_lib_wikibase_srl_visitor visitor = new Scrib_lib_wikibase_srl_visitor(); @@ -40,4 +54,8 @@ class Scrib_lib_wikibase_srl_visitor_fxt { Keyval[] actlGeo = (Keyval[])actl[1].Val(); Gftest.Eq__double(expd, Double_.cast(actlGeo[4].Val())); } + public void TestCalcPrecision(String expd, String prc, String lng) { + Decimal_adp actl = Scrib_lib_wikibase_srl_visitor.CalcPrecision(Bry_.new_u8(prc), Bry_.new_u8(lng)); + Gftest.Eq__str(expd, actl.To_str("0.0E0")); + } } \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/xtns/wbases/claims/itms/Wbase_claim_globecoordinate.java b/400_xowa/src/gplx/xowa/xtns/wbases/claims/itms/Wbase_claim_globecoordinate.java index 110c6d076..3d25b59a6 100644 --- a/400_xowa/src/gplx/xowa/xtns/wbases/claims/itms/Wbase_claim_globecoordinate.java +++ b/400_xowa/src/gplx/xowa/xtns/wbases/claims/itms/Wbase_claim_globecoordinate.java @@ -38,14 +38,6 @@ public class Wbase_claim_globecoordinate extends Wbase_claim_base { public byte[] Glb_ttl() {return glb_ttl;} private byte[] glb_ttl; public void Glb_ttl_(byte[] v) {glb_ttl = v;} - public Decimal_adp Prc_as_num() { - if (prc_as_num == null) { - prc_as_num = Bry_.Eq(prc, Object_.Bry__null) - ? Decimal_adp_.Zero // 2020-09-03|ISSUE#:792|null precision should default to 0 not 1;PAGE:wd:Q168751 - : Decimal_adp_.parse(String_.new_a7(prc)); - } - return prc_as_num; - } private Decimal_adp prc_as_num; @Override public void Welcome(Wbase_claim_visitor visitor) {visitor.Visit_globecoordinate(this);} @Override public String toString() {// TEST: