From b2ef17504d7dfd7cfe652c7097e4679df3fd3386 Mon Sep 17 00:00:00 2001 From: Ian Dees <ian.dees@gmail.com> Date: Mon, 15 Jul 2013 21:48:26 -0500 Subject: [PATCH] Initial commit of plugin based on walking papers plugin. --- .classpath | 7 + .gitignore | 3 + .project | 17 + README | 6 + build.xml | 30 ++ data/bg.lang | Bin 0 -> 48 bytes data/ca.lang | Bin 0 -> 331 bytes data/cs.lang | Bin 0 -> 277 bytes data/da.lang | Bin 0 -> 102 bytes data/de.lang | Bin 0 -> 323 bytes data/el.lang | Bin 0 -> 131 bytes data/en.lang | Bin 0 -> 312 bytes data/en_AU.lang | 1 + data/en_GB.lang | 1 + data/es.lang | Bin 0 -> 297 bytes data/et.lang | Bin 0 -> 166 bytes data/eu.lang | Bin 0 -> 297 bytes data/fr.lang | Bin 0 -> 371 bytes data/gl.lang | Bin 0 -> 212 bytes data/id.lang | Bin 0 -> 301 bytes data/it.lang | Bin 0 -> 345 bytes data/ja.lang | Bin 0 -> 341 bytes data/nl.lang | Bin 0 -> 302 bytes data/pl.lang | Bin 0 -> 275 bytes data/pt.lang | Bin 0 -> 392 bytes data/pt_BR.lang | Bin 0 -> 293 bytes data/ru.lang | Bin 0 -> 433 bytes data/sk.lang | Bin 0 -> 296 bytes data/uk.lang | Bin 0 -> 440 bytes data/zh_CN.lang | Bin 0 -> 284 bytes data/zh_TW.lang | Bin 0 -> 284 bytes images/preferences/walkingpapers.png | Bin 0 -> 1910 bytes images/walkingpapers.png | Bin 0 -> 361 bytes .../FieldPapersAddLayerAction.java | 105 +++++ .../plugins/fieldpapers/FieldPapersKey.java | 78 ++++ .../plugins/fieldpapers/FieldPapersLayer.java | 427 ++++++++++++++++++ .../fieldpapers/FieldPapersPlugin.java | 33 ++ .../plugins/fieldpapers/FieldPapersTile.java | 67 +++ 38 files changed, 775 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 README create mode 100644 build.xml create mode 100644 data/bg.lang create mode 100644 data/ca.lang create mode 100644 data/cs.lang create mode 100644 data/da.lang create mode 100644 data/de.lang create mode 100644 data/el.lang create mode 100644 data/en.lang create mode 100644 data/en_AU.lang create mode 100644 data/en_GB.lang create mode 100644 data/es.lang create mode 100644 data/et.lang create mode 100644 data/eu.lang create mode 100644 data/fr.lang create mode 100644 data/gl.lang create mode 100644 data/id.lang create mode 100644 data/it.lang create mode 100644 data/ja.lang create mode 100644 data/nl.lang create mode 100644 data/pl.lang create mode 100644 data/pt.lang create mode 100644 data/pt_BR.lang create mode 100644 data/ru.lang create mode 100644 data/sk.lang create mode 100644 data/uk.lang create mode 100644 data/zh_CN.lang create mode 100644 data/zh_TW.lang create mode 100644 images/preferences/walkingpapers.png create mode 100644 images/walkingpapers.png create mode 100644 src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersAddLayerAction.java create mode 100644 src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersKey.java create mode 100644 src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersLayer.java create mode 100644 src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersPlugin.java create mode 100644 src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersTile.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..663bc1b --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/JOSM"/> + <classpathentry kind="output" path="build"/> +</classpath> diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98217d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +.settings + diff --git a/.project b/.project new file mode 100644 index 0000000..8a6fe0e --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>JOSM-walkingpapers</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/README b/README new file mode 100644 index 0000000..52fa214 --- /dev/null +++ b/README @@ -0,0 +1,6 @@ +A plugin for displaying tiled, scanned maps from walking-papers.org. + +Written by Frederik Ramm <frederik@remote.org>, based on SlippyMap +plugin work by Lubomir Varga <lubomir.varga@freemap.sk> or <luvar@plaintext.sk>. + +Public Domain. diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..34ac7d5 --- /dev/null +++ b/build.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** This is a template build file for a JOSM plugin. +** +** Maintaining versions +** ==================== +** See README.template +** +** Usage +** ===== +** Call "ant help" to get possible build targets. +** +--> +<project name="walkingpapers" default="dist" basedir="."> + + <!-- enter the SVN commit message --> + <property name="commit.message" value="Changed the constructor signature of the plugin main class"/> + <!-- enter the *lowest* JOSM version this plugin is currently compatible with --> + <property name="plugin.main.version" value="4549"/> + + <property name="plugin.author" value="Frederik Ram"/> + <property name="plugin.class" value="org.openstreetmap.josm.plugins.walkingpapers.WalkingPapersPlugin"/> + <property name="plugin.description" value="Supports downloading tiled, scanned maps from walking-papers.org. This plugin is still under early development and may be buggy."/> + <property name="plugin.icon" value="images/preferences/walkingpapers.png"/> + <property name="plugin.link" value="http://wiki.openstreetmap.org/index.php/JOSM/Plugins/WalkingPapers"/> + + <!-- ** include targets that all plugins have in common ** --> + <import file="../build-common.xml"/> + +</project> diff --git a/data/bg.lang b/data/bg.lang new file mode 100644 index 0000000000000000000000000000000000000000..b30d90fcf8001b62ab5cf415b89d10e9f45a0bbb GIT binary patch literal 48 ucmZQz00V^!3oq=tu;Ieq3p*}0fawhiAc2bw7n?3@(9_ccsrvu#|9=2BiWy=6 literal 0 HcmV?d00001 diff --git a/data/ca.lang b/data/ca.lang new file mode 100644 index 0000000000000000000000000000000000000000..1e75f2920f82c85580a984f8452120b99e793aa1 GIT binary patch literal 331 zcmZvYF;2rk5Ji0kPVkk+Nr43gB~U;Ui2y=E)D!QpSs3pwvvyKMIS-<u;0V4~%$ih4 z>AprY|Nl3|!+pStz^SDcF{I>{!Y~XGwoc*vYtV*j*Z+X9A$fP+o<@qSsS0Y51*9zJ zx0r0tc9Y_25mKw9=sX&VqjgQ5-?F_!O{#3OB*BK4NBjyq_pJug_1|5#Adpe+KXY_m z&$W&;2xC;vpR!<05)>aDW93FJ!zpV2mB!O+XD%~?5T2jzX2r?kf4i!xhJA5yGfrO) goOt}>#59x5z#iVMSp=pmsfpqaZ`q#jhW#-70^Ry}mH+?% literal 0 HcmV?d00001 diff --git a/data/cs.lang b/data/cs.lang new file mode 100644 index 0000000000000000000000000000000000000000..cff2b09d0c5f1fdf3b31e1a15177d8023759d42c GIT binary patch literal 277 zcmZvXQA)#55Jle}+`y$2Qo#mYfE2+WK}xZx;NQedYe@3u@m`FW(j~Zner5q~!Jn9I zHBRfN!hFnJhI`L7S95lfQoqXzL10+={^&kKh0LzRm-NhN@J2<R+4a<sV;^GiYusET ziZ<ulC^GXWNjx<u$-SN-uh@4jlJ|n(`W>fSs%gmCO5L@VKzhFDi>^9<t<CJAkp8P; z+~3{8aw3PYiDI>ib<i5ZXqKgyqtk!c%*pbYMpii#iV(-~us7q!-x^pPYoPX_stFTq Op++JlHW%ArKMX(l)@jB7 literal 0 HcmV?d00001 diff --git a/data/da.lang b/data/da.lang new file mode 100644 index 0000000000000000000000000000000000000000..e682717308f5db0c93b811f20ac0b7435700252c GIT binary patch literal 102 zcmXAh(FuSs3<a}+D`Ww)h64!x2OCOgXiHjgduzqNciiy+U^}#-bWFuN265~fOryBq qgm!Yy)0T)=wZdWUu7)>T(j3>yRlHI02ms5T{`&hOqVWKXXN(v6za{4Y literal 0 HcmV?d00001 diff --git a/data/de.lang b/data/de.lang new file mode 100644 index 0000000000000000000000000000000000000000..76868a2967122a444a77f3c803236dcde4e9d8c1 GIT binary patch literal 323 zcmZwDv2MaJ5C&ks085|X7efUD7JY!KOA$gaAlj-Dn;ReYsmUF35*QG#-qfU7Dlwkq z`~CfAHft4W2%ZTmIcTa}!zv^=so?C&Z<a7Sx+A69Y6_^hfu{ua7+>bsF@%fQpro3_ z?DoWgKrDo{OGEBSQ_LHI>cZvE(29p^5BJie7BNuid<LA`<jI=tlD_ivmVtfl9n;5d z1HGYEubA9c--%0zD<WRlKZB(w=VwzmF%Qc@G9azBX7u@2b=x;JkN?KmA`1wU+;`d^ OV6R%?@^tNfy6zVMd~!(u literal 0 HcmV?d00001 diff --git a/data/el.lang b/data/el.lang new file mode 100644 index 0000000000000000000000000000000000000000..9c9af41ac13eaf58eb57d76d745e19143efddba0 GIT binary patch literal 131 zcmZQz00X6Si_dL5-*~?B+@5o5&+R?8|9q3ex#j290EJr4Z9m_nr>DoD1{46PX*sv^ n+!}@R4M0V$AZja6tN|#~a&8S!=T@M3+Qg}}Qm8hl{r?{T4H-?c literal 0 HcmV?d00001 diff --git a/data/en.lang b/data/en.lang new file mode 100644 index 0000000000000000000000000000000000000000..a4c40e86ecbeea890f646e394475edeb8fb2c6a0 GIT binary patch literal 312 zcmZvXL2Cjr5QXy#yz~z|JQO_`^jau;P(eXKTBPS`leMAQOh~d8EB<ynYkOJnHjjDp z=6$M~bL$NP7bHstF4UYFDvkr{#0|d5f4Oj&M2a?L&FO&hY2gfp=jmmrHVc=drxOSb zMcGl2n~a$3(Q%vo3HgIUum%(i+US{#h{AWG)oK}vO_Fuz?fzv0PFOE6>KeSe0;)TA zrz&TjrTlFc<5&$||G#c2YOU4a?GFUI8;E-BYY2iwjf833<@~U)pJx~K(Dyw-9M|hF D)EsPN literal 0 HcmV?d00001 diff --git a/data/en_AU.lang b/data/en_AU.lang new file mode 100644 index 0000000..30b6b2b --- /dev/null +++ b/data/en_AU.lang @@ -0,0 +1 @@ +ÿþÿþÿþÿþÿþÿþÿþÿÿ \ No newline at end of file diff --git a/data/en_GB.lang b/data/en_GB.lang new file mode 100644 index 0000000..30b6b2b --- /dev/null +++ b/data/en_GB.lang @@ -0,0 +1 @@ +ÿþÿþÿþÿþÿþÿþÿþÿÿ \ No newline at end of file diff --git a/data/es.lang b/data/es.lang new file mode 100644 index 0000000000000000000000000000000000000000..20ff18a58861da1bb165766d7d47bcc2ae04c570 GIT binary patch literal 297 zcmZ`!OG*Pl6znT_gCZa#3kP!m5iy&9kq`*3U#6d-lbL>Pe-I5hkZX^Sdu4pB;7WHz zQD1ZSC`gP@te|6#=m^d~OYEt2r%w;dc%^Rd{PrqP;FubTTW|+wF*;lyM`pQ@lp{qH zkDdbIr7$>U+7QTRj!x59fs!qGCaroyDjTPO{zx~gxzAB-X<0J~>(#?QGo*ITXBh8F z%A%qa%IPCj^{ulvU|;{Je_}2cb=vQOrfG(=xxBCB)6YLFzyD#ZuO`*{F4E&LJr3t# F_yWqOYoh=F literal 0 HcmV?d00001 diff --git a/data/et.lang b/data/et.lang new file mode 100644 index 0000000000000000000000000000000000000000..64329c7764ed59e549aa29e83a6a45d35a76d377 GIT binary patch literal 166 zcmZvVu?@m75JhhY2DlOmya7r94T6e@0Z#HMy7=ToKF3*z6__A<#h_Falwa@ZeE?`~ zQz2y5$b~ec1&Yi`^5n56oJoVk?l{uO$=r}SR3g9OK$J3^TQRo$SA9P2SeCco^@98F g5W`0N3H#-hSaDD;I2avZ*Z$mYUFTd~0qR=o2U4&;CIA2c literal 0 HcmV?d00001 diff --git a/data/eu.lang b/data/eu.lang new file mode 100644 index 0000000000000000000000000000000000000000..f6bb522748851decd99d24315637a7b03ddf0a57 GIT binary patch literal 297 zcmZvX!D_-#5JlflbU(OKN`n1>QYdC2xG0Laz9rK*#JmZU7Ya}Ob<;^pcW#G!&zu{o zDoZ5Eh*X2VacLzsMUS3sDAk&xRa#uvw*_rC1&lo#ztlQpQIHtg(M-boj?Wy?DDluD zGSWz#9s<p4o~s?zp$GBINP~p^0p_*G4#)kDxK>AQH}r`_OTV}@8aA0>pf{;s>8v(O z>W~<56`rbpodjPpKP<~~x`*e}-&Feeok~mJxFUy*8FYQQQC97W4st=9?$h)GL0fD2 literal 0 HcmV?d00001 diff --git a/data/fr.lang b/data/fr.lang new file mode 100644 index 0000000000000000000000000000000000000000..96d09143979f744b8ff720757aee8816fff2cc75 GIT binary patch literal 371 zcmZutOG*Pl5bYDV@&IpVvQTs@h)8geMZlfwn(3O@q^G;>PlASk*YF0;Ip!uF#Icen z1S1qh74_=Xd!?#r8+=NpvJB0zCQ9N2;~F1Z%Er4SgHTMuitNI;`FWtgF<tmLNAM-W ze!jgM%`Th9kjs!(Vtu*U7ixCbG^T#yh~gME#moq?@9MtO+_tiaRFiXk$KVWhOaHR1 zlW-s3REv9;;}03>$SE;aT>S%uFLDxx+D4YJB+EigqTwTnTihCb15M&|Yvq7*tWG97 qxxe~`FLgE{`&<~0`)}Z3_YI81?-*3@>V1p#)kdBEL0m&1!|)B6F_BCF literal 0 HcmV?d00001 diff --git a/data/gl.lang b/data/gl.lang new file mode 100644 index 0000000000000000000000000000000000000000..d2e3f733f2b6dee9f011298a8e7c0eeeda8b7e9b GIT binary patch literal 212 zcmZvWF$%&!5JmS2-r!fFg^M0R(g}*4^_Wb;qPw&18U;g6WNB#^@0FM+SlNC)?>&`l z#33?#X)?i)0|>_D5-g?W^>D}-S2`YyD`uWNho~hKNChTCbFb!g^Hi&)l}G`lgC$Qm zm5f{reBg^A%kIqJn37}aC5%|^2OIq%E2T#3f${rmt-Dr@lVRL_OR)Wv0F&N7?R#+( Lv8Wbx*LK|-TiZ_M literal 0 HcmV?d00001 diff --git a/data/id.lang b/data/id.lang new file mode 100644 index 0000000000000000000000000000000000000000..e161a7ced01bcdef2828e27d5e24e0688f055340 GIT binary patch literal 301 zcmZvXyH3ME6h!?M)T2~M!RrHnh6V(Zg@UNZ*^9aC!`7}>$cpmoF>4G|DQ-9S%$(|W ztA-YaJqLL44R?fw_bz%Sg&M5(SBF&zM8y}K)zF^z>?Nj)F1A&@&EYd!%Ya@6Vq|EM zq!E{W7>Pj~KVTGTS0ZLUMebck11qP9kIzgC@b%>h9GLNNk9EUV%XgB6c&FxOMj1MK vl;q|V>#Y9Y^fzSQF&(SRx5WkZj|&_}iC7oc%`dYkHj)@i>HhjK9jECV#D{HM literal 0 HcmV?d00001 diff --git a/data/it.lang b/data/it.lang new file mode 100644 index 0000000000000000000000000000000000000000..3f8e5d41e69c2a2cf4c23e8c8ce5713556d56aac GIT binary patch literal 345 zcmZvYK~BRk5Jhte)?eMUT@V3##D)ctiiD5=vFl(DVT9wc>;$A#y$|=`UQO+=Lh8o0 zX6FBS-_>2y1x-ob#4#MVEyr?0{JX}EMo}-Y?A&rG7K`1*egRAPCif}6Jr5K(rdnfL zZJ#9#<YXKPgC}$p0>OMRet(d9>IosTVavYft{g~)yysXXxyvvV#gu0nPHlK?e9F@q zaPS$>N>M7F9yicZYHqP|c?-qtZ8a#w;YRE={2U+;u3_br_1XPQ`wytD>*-KkZR9Jf f6)%60@i0fmDu2ZqMhi(BDbtipirwXYI!x0Md?<ej literal 0 HcmV?d00001 diff --git a/data/ja.lang b/data/ja.lang new file mode 100644 index 0000000000000000000000000000000000000000..0874920336a773ca075de91c4ed173851e52ff43 GIT binary patch literal 341 zcmZvY&q_j35Qoo`#KBcTUFrd%O`D)a2~k_YkV{cwixwhuW)QMJ1WCEL!L?G0%2VN{ zOzdHPp6V&QO{bM0%xY%%ecy~)-Op@qg*&;Kd?vqH*b8<GISq3Rs=(MUF1z|G==|rQ z4fE;FE<q<SeV7PTg}H;N!NfSAFbngnQ^na*N^J~2nyzvRdIz<^x8RQ7YmG%cf^NVJ zu7PE{2Nv>$=fv*n#YLSz{`LKLqpQ+m6YN@gS)9cx7Kx=rJt>XBn;2WY5N79PW?f&r zEx77Yhf|X2%1w6^sfkg~5poa&$xuy$x?ZeaoGVGn`v1rDivJk+3Df{f_2m3ym?XbO CHNqGG literal 0 HcmV?d00001 diff --git a/data/nl.lang b/data/nl.lang new file mode 100644 index 0000000000000000000000000000000000000000..8c957181167d48de3e169097ddcdd2f82eb4d136 GIT binary patch literal 302 zcmZvX!D<3Q5Jcw}@&|<w(1VNl0LdYOh&f2W<lH#D<Fe!QGCR1S_-EeoU#>m7$K*7{ zP+j%Pd~7AaF$Ywklz5_4F+5-N<4l1{bmZ$QxOqbj$F`8@a2AQMjLiy@>*6*syESu} zkW*@+n9wn+LzDEiDm!Ymq&-luP?O`|d*g*Hg4+M7F#B)OvmChp`h=9ZYkK6Qr<U0# z1|5zmmoVNdyHxrt)jZ2`ApA>iUe+T7kDNtO^bhm;Gfu>Am^k-D4pSXAL|sHqxW3)` HN8djI*lui7 literal 0 HcmV?d00001 diff --git a/data/pl.lang b/data/pl.lang new file mode 100644 index 0000000000000000000000000000000000000000..768900c3f357ae56e0b0db28d3a16b1c43aacba0 GIT binary patch literal 275 zcmZvWF;2rk6h!w9Tws(6B(TB_DALd%7f48SAA7OBH{QS6wYADdX=rkWD950s!@gFW z1sWufrkG+h@2R^7*65@e4{$!|Ds6fi_h9=fzN4yTBt%*pw#|(rr+p~IHxO`*#df({ zsK-(aO&{pU<rC9?zI#HF(9`rrh*i?l(XwulbTDKkk|i*rPeUcS=KKYy>r!fJLABQb z>){3Wt1rUlUmbPv{Odc<s3?m0q?S)V<|x0-GslNM5-zj&6(XEO9uFoYZF#`<b~m5q F`3w$3YbF2y literal 0 HcmV?d00001 diff --git a/data/pt.lang b/data/pt.lang new file mode 100644 index 0000000000000000000000000000000000000000..023ba19fe2a3b42d214a2c909aa33ba8260fbd8d GIT binary patch literal 392 zcmZutJ5B>J5Zyy?fKjTXzzPRI6wsttKth5NP4Hwj%G%@gCy^56G!#@^fOhYd#olc| z&^_7nzEyYMzYA=H!AS`H=Z;#CbtDf01|5PG2pkFa*lyW2mku5Ipu{)uCMI94?qGIY zo@NT3$@7N0MERAhCQtoGMi9wn0ZmzJC#rg_B}9*q%;fO!RF6_tA_ge*F^;DlqnW7O zaKx4msEZ!i{F9NxtnxQkrB^n3(dmG{g6wHsd|XRWAk)WslBNoC0o#8W@&X8fn#4YX z8`js0lKdZ+i@MCCe?(JC4d-fkiv~5q%QP4~j)TEGZ?q_DlI;>|KUNbsUY&;XFnj~B C(U89Y literal 0 HcmV?d00001 diff --git a/data/pt_BR.lang b/data/pt_BR.lang new file mode 100644 index 0000000000000000000000000000000000000000..8f1965fea3b92bcf42b71f5d5389f2f48ece2cdb GIT binary patch literal 293 zcmZvXF-`+95Ji0jZt#_cq+kUHKokU_NCBZph<b=8k;U5M*la*VISmD(pyUL;SC(-i zsObI_^Zxs0d|TcH<r7hIE?;YI(Q<+d3rU{JNBQOqD|n&y$%W-fq{t~_E*=7BG1#1L z2WEEl>K+-Lho?wbb&Q2LP<ZC#6vP_9c}{^zVVc9*)f6d_f_~|GS9~LBX|5-Ghe{>f z&!&(Llkq<;L#h}pupGsyE#t!3bA<id$Q<2Nr@!{5Y5JWxz9dhU@Nn3LyTh)b&KV&H O-b5E}&bIxo?|%S(CTpbt literal 0 HcmV?d00001 diff --git a/data/ru.lang b/data/ru.lang new file mode 100644 index 0000000000000000000000000000000000000000..3de0c373f93b29b4a82b06cf44ca4b0ac7ad42d6 GIT binary patch literal 433 zcmZvY!AiqW5JmGTLslth(1lBJ<3?~Hg6OsoDM8Uv7cNR6X+;Z)f_oAF;I$eXO%s3N z&JQ)-N!{7ad%T%>=iWPBgcoF(qQVSwo}VaD34Sy|rFY162&Y4R5acNJhQ)+)PH)+I zwBk(s>-PCse9>9&w!5djtMIbd@kt;ij>PY8418~lSF*q1sPc#7LlcrmYr;lF9YZ^P z61(UkLnfH$JqkFn0Zki1NoAU&XPaUx7o*~xxDowl%c`~h8}m-^%%2%PnrN9E9qwC- zf|R{o2^iUFx(v(&lq_gtCyurSQyXqcgI_@o@V3GqZ7`BGEG=9ZhV{bR;%vbTUlMRX dEjeCpP!5_6npCsoRLAxQ6ME=x4(df+{{o$E|J?up literal 0 HcmV?d00001 diff --git a/data/sk.lang b/data/sk.lang new file mode 100644 index 0000000000000000000000000000000000000000..0c7dc14ac5ac57220306cc07e607800c82ce0748 GIT binary patch literal 296 zcmZvXF;2rk5JmS6T;MBJQefZ!2nrga2q6$4(T(vY+1R^dt(Qe|lq2L2mY_^WOPY<Z z6=yL8O{y8`f6crnuJ5D{-|bdv?ABr9sQrR6Q?@!ZZ%U%Z2Nk(8v(u7FX{&_o3~nx= zG7OgItAQB5a%!oDrt%%RV;dTzTo6htGZ%g|s$3fOWMV)tG`F;f<H%t#c`mr!s>qP> zksMDC6R^eY4TirAsdAvHleQ<iQrTr>@Ap_7iId0w$B~YZBuTdyXD@$7xbKbNZRI>+ Y7;Q%IjM|6K-MVe02^%agR^7hq4!`zwBLDyZ literal 0 HcmV?d00001 diff --git a/data/uk.lang b/data/uk.lang new file mode 100644 index 0000000000000000000000000000000000000000..62b22a1860cd8d6701b74ca32da53c032680cc83 GIT binary patch literal 440 zcmZ`#yGjE=6x}b8+ie0WinZ9-2o@rUjZHuaLD3Kki?Fhfpee+F#dab#V!0bO8ceeJ zg>!$w56OD&qzo1_%zd249528tMuH&<WSF4TNC$$shI~F^tT8g4v1p2!_Sg(DW$Qsx zeHMJnUE}Jqb=}-(H`*7S+s&I!lU-!CUtmNG!P;Z><A@AjVk*Ah-3ol)yT==A&J5&) z++wJ)ChMXDtAv=0OsV$GYOV>5vKu+vjQF9=ov0IE)@B`F=7AG;t$Ov&@WSm83bM!g zBqzs*LRgMc4)&$S2r?$ZKTtohTvEzT7|~wqe3!8qp#CrW8s1ktT6~xz`wc&;g|~xG hDuhyF9CbNehABrbOrv*UN7{Fv$u*Vkc2F&<>JQ>x1+xGE literal 0 HcmV?d00001 diff --git a/data/zh_CN.lang b/data/zh_CN.lang new file mode 100644 index 0000000000000000000000000000000000000000..d0cabe27b2fe1f45c626ca1408097e40c670e841 GIT binary patch literal 284 zcmZRucs6~(v&~bV?Cw)2Pt3{A%uClTNGwP#D%Q&{N>_NXe)rS<X$qMsj~eDw8`M5( znEQNI%ai>JpEa&$uzogU-}5EAp0;*8?d*Nlx%ydu|I?k@p6uv)vS-25jt$t118ROc zXT#Ik`xx9_?3?_wbtyJQp+P<h&pM_lc)DmjowGs##C@`3t%7}Kimk$vo!w6-^Z|`| z*}URuN1G;t5X54*!Fqan|Nk-QhC{rf5CHay0?@{%8=EwMKG1x>r|0>emCvT^d%kP= X(~i{&)rPeUBB;vW@0kTu`TsuvUJ{do literal 0 HcmV?d00001 diff --git a/data/zh_TW.lang b/data/zh_TW.lang new file mode 100644 index 0000000000000000000000000000000000000000..6685442b5f889a403a5962d5e0361c7e51390b1a GIT binary patch literal 284 zcmZRuc;2$`+2*NF_svr%Pt3{A%uClTNGwP#D%Q&{N>_NXuHk9_G=<ER#|=Hz2DOhH zdY{i~d9k_u#fmNl>z51HKVP!zX=}&R&faHz&CmM#pX^xnWJlN2rp-?~HefRjsQKxf z4NvDxWAJ#fXUEglrPvgO2KgvF>zJnC>7t<Vbj}I|5dX=JwF(OMnJKmkPj+@c-PZ#& z=w<VYryXsY3_=jA;YRD}>HYu5pdAkJj6wj|GYUXEpKe^DpaJxR=KDQ8&!+8pzGL09 WDf<+v4Qm-hP!+%5GYhEf|9=1x%#gwW literal 0 HcmV?d00001 diff --git a/images/preferences/walkingpapers.png b/images/preferences/walkingpapers.png new file mode 100644 index 0000000000000000000000000000000000000000..ea185998e011bd3852b7e292b73a46c4f09231e0 GIT binary patch literal 1910 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 literal 0 HcmV?d00001 diff --git a/images/walkingpapers.png b/images/walkingpapers.png new file mode 100644 index 0000000000000000000000000000000000000000..054bafc4a103d3b8e7d3287d3bb9965e1cabdc32 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggac77f;%eM5Jo<O0Oo-U3d7N>iI z4^BK{z%e<0o4!Ztj8hY|AKP^wzj>qj_;IC^Cp<KG-v?a{37ylWa^}shb=|l5tKLfr z&YanAY#bbFtYoB=xBbtW-c^V0GBUj53uQgod0+UL*QZ;)#>X0F`ffUObutgb+tn?v zxYM7#{S(~Ok<h~!+S)Ot^Yh<n4NtE9z4ZQ_!Di!w5|1A`+bVMk{<L%Kjk<AHQEBo9 zkA9Zb;?_B7{4@DEmwqjts+v6YXGC(ETEom;rBkzw`m;;QzuZ%g`#S&CG#6v%Y+gab z$=jbTSX8T`(Alwrb;XCQS5|?)-@pG;DR`2NVgGrTpEDf19`6Twn!(f6&t;ucLK6T7 Cbd>V| literal 0 HcmV?d00001 diff --git a/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersAddLayerAction.java b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersAddLayerAction.java new file mode 100644 index 0000000..ac3eb9b --- /dev/null +++ b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersAddLayerAction.java @@ -0,0 +1,105 @@ +package org.openstreetmap.josm.plugins.fieldpapers; + +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.awt.event.ActionEvent; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.JOptionPane; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.actions.JosmAction; +import org.openstreetmap.josm.data.Bounds; +import org.openstreetmap.josm.data.coor.LatLon; + +@SuppressWarnings("serial") +public class FieldPapersAddLayerAction extends JosmAction { + + public FieldPapersAddLayerAction() { + super(tr("Scanned Map..."), "walkingpapers", + tr("Display a map that was previously scanned and uploaded to walking-papers.org"), null, false); + } + + public void actionPerformed(ActionEvent e) { + String wpid = JOptionPane.showInputDialog(Main.parent, + tr("Enter a walking-papers.org URL or ID (the bit after the ?id= in the URL)"), + Main.pref.get("walkingpapers.last-used-id")); + + if (wpid == null || wpid.equals("")) return; + + // Grab id= from the URL if we need to, otherwise get an ID + String mungedWpId = this.getWalkingPapersId(wpid); + + if (mungedWpId == null || mungedWpId.equals("")) return; + + // screen-scrape details about this id from walking-papers.org + String wpUrl = Main.pref.get("walkingpapers.base-url", "http://walking-papers.org/") + "scan.php?id=" + mungedWpId; + + Pattern spanPattern = Pattern.compile("<span class=\"(\\S+)\">(\\S+)</span>"); + Matcher m; + + double north = 0; + double south = 0; + double east = 0; + double west = 0; + int minz = -1; + int maxz = -1; + String tile = null; + + try { + BufferedReader r = new BufferedReader(new InputStreamReader(new URL(wpUrl).openStream(), "utf-8")); + for (String line = r.readLine(); line != null; line = r.readLine()) { + m = spanPattern.matcher(line); + if (m.find()) { + if ("tile".equals(m.group(1))) tile = m.group(2); + else if ("north".equals(m.group(1))) north = Double.parseDouble(m.group(2)); + else if ("south".equals(m.group(1))) south = Double.parseDouble(m.group(2)); + else if ("east".equals(m.group(1))) east = Double.parseDouble(m.group(2)); + else if ("west".equals(m.group(1))) west = Double.parseDouble(m.group(2)); + else if ("minzoom".equals(m.group(1))) minz = Integer.parseInt(m.group(2)); + else if ("maxzoom".equals(m.group(1))) maxz = Integer.parseInt(m.group(2)); + } + } + r.close(); + if ((tile == null) || (north == 0 && south == 0) || (east == 0 && west == 0)) throw new Exception(); + } catch (Exception ex) { + JOptionPane.showMessageDialog(Main.parent,tr("Could not read information from walking-papers.org the id \"{0}\"", mungedWpId)); + return; + } + + + //http://walking-papers.org/scan.php?id=rmvdr3lq + // The server is apparently broken and returning the WpId in the URL twice + // which makes it return errors when we fetch it. So, strip out one of + // the dups. This is a hack and needs to get removed when the server + // is fixed. + tile = tile.replaceFirst(mungedWpId+"/"+mungedWpId, mungedWpId); + Main.pref.put("walkingpapers.last-used-id", mungedWpId); + + Bounds b = new Bounds(new LatLon(south, west), new LatLon(north, east)); + + FieldPapersLayer wpl = new FieldPapersLayer(mungedWpId, tile, b, minz, maxz); + Main.main.addLayer(wpl); + + } + + private static String getWalkingPapersId(String wpid) { + if (!wpid.contains("id=")) { + return wpid; + } else { + // To match e.g. http://walking-papers.org/scan.php?id=53h78bbx + final Pattern pattern = Pattern.compile("\\?id=(\\S+)"); + final Matcher matcher = pattern.matcher(wpid); + final boolean found = matcher.find(); + + if (found) { + return matcher.group(1); + } + } + return null; + } +} diff --git a/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersKey.java b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersKey.java new file mode 100644 index 0000000..8d5f759 --- /dev/null +++ b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersKey.java @@ -0,0 +1,78 @@ +/** + * + */ +package org.openstreetmap.josm.plugins.fieldpapers; + +/** + * <p> + * Key for map tile. Key have just X and Y value. It have overriden {@link #hashCode()}, + * {@link #equals(Object)} and also {@link #toString()}. + * </p> + * + * @author LuVar <lubomir.varga@freemap.sk> + * @author Dave Hansen <dave@sr71.net> + * + */ +public class FieldPapersKey { + private final int x; + private final int y; + private final int level; + + /** + * <p> + * Constructs key for hashmaps for some tile describedy by X and Y position. X and Y are tiles + * positions on discrete map. + * </p> + * + * @param x x position in tiles table + * @param y y position in tiles table + */ + public final boolean valid; + public FieldPapersKey(int level, int x, int y) { + this.x = x; + this.y = y; + this.level = level; + if (level <= 0 || x < 0 || y < 0) { + this.valid = false; + System.err.println("invalid WalkingPapersKey("+level+", "+x+", "+y+")"); + } else { + this.valid = true; + } + } + + /** + * <p> + * Returns true ONLY if x and y are equals. + * </p> + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof FieldPapersKey) { + FieldPapersKey smk = (FieldPapersKey) obj; + if((smk.x == this.x) && (smk.y == this.y) && (smk.level == this.level)) { + return true; + } + } + return false; + } + + /** + * @return return new Integer(this.x + this.y * 10000).hashCode(); + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return new Integer(this.x + this.y * 10000 + this.level * 100000).hashCode(); + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "WalkingPapersKey(x=" + this.x + ",y=" + this.y + ",level=" + level + ")"; + } + +} diff --git a/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersLayer.java b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersLayer.java new file mode 100644 index 0000000..421dec5 --- /dev/null +++ b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersLayer.java @@ -0,0 +1,427 @@ +package org.openstreetmap.josm.plugins.fieldpapers; + +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.image.ImageObserver; +import java.net.URL; +import java.util.Comparator; +import java.util.HashMap; +import java.util.TreeSet; + +import javax.swing.Action; +import javax.swing.Icon; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.data.Bounds; +import org.openstreetmap.josm.data.coor.LatLon; +import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; +import org.openstreetmap.josm.gui.MapView; +import org.openstreetmap.josm.gui.MapView.LayerChangeListener; +import org.openstreetmap.josm.gui.dialogs.LayerListDialog; +import org.openstreetmap.josm.gui.dialogs.LayerListPopup; +import org.openstreetmap.josm.gui.layer.Layer; +import org.openstreetmap.josm.tools.ImageProvider; + +/** + * Class that displays a slippy map layer. Adapted from SlippyMap plugin for Walking Papers use. + * + * @author Frederik Ramm <frederik@remote.org> + * @author LuVar <lubomir.varga@freemap.sk> + * @author Dave Hansen <dave@sr71.net> + * + */ +public class FieldPapersLayer extends Layer implements ImageObserver { + /** + * Actual zoom lvl. Initial zoom lvl is set to + * {@link WalkingPapersPreferences#getMinZoomLvl()}. + */ + private int currentZoomLevel; + private HashMap<FieldPapersKey, FieldPapersTile> tileStorage = null; + + private Point[][] pixelpos = new Point[21][21]; + private LatLon lastTopLeft; + private LatLon lastBotRight; + private int viewportMinX, viewportMaxX, viewportMinY, viewportMaxY; + private Image bufferImage; + private boolean needRedraw; + + private int minzoom, maxzoom; + private Bounds printBounds; + private String tileUrlTemplate; + private String walkingPapersId; + + @SuppressWarnings("serial") + public FieldPapersLayer(String id, String tile, Bounds b, int minz, int maxz) { + super(tr("Walking Papers: {0}", id)); + setBackgroundLayer(true); + walkingPapersId = id; + + tileUrlTemplate = tile; + this.printBounds = b; + this.minzoom = minz; this.maxzoom = maxz; + currentZoomLevel = minz; + + clearTileStorage(); + + MapView.addLayerChangeListener(new LayerChangeListener() { + public void activeLayerChange(Layer oldLayer, Layer newLayer) { + // if user changes to a walking papers layer, zoom there just as if + // it was newly added + layerAdded(newLayer); + } + + public void layerAdded(Layer newLayer) { + // only do something if we are affected + if (newLayer != FieldPapersLayer.this) return; + BoundingXYVisitor bbox = new BoundingXYVisitor(); + bbox.visit(printBounds); + Main.map.mapView.recalculateCenterScale(bbox); + needRedraw = true; + } + + public void layerRemoved(Layer oldLayer) { + if (oldLayer == FieldPapersLayer.this) { + MapView.removeLayerChangeListener(this); + } + } + }); + } + + /** + * Zoom in, go closer to map. + */ + public void increaseZoomLevel() { + if (currentZoomLevel < maxzoom) { + currentZoomLevel++; + needRedraw = true; + } + } + + /** + * Zoom out from map. + */ + public void decreaseZoomLevel() { + if (currentZoomLevel > minzoom) { + currentZoomLevel--; + needRedraw = true; + } + } + + public void clearTileStorage() { + tileStorage = new HashMap<FieldPapersKey, FieldPapersTile>(); + checkTileStorage(); + } + + static class TileTimeComp implements Comparator<FieldPapersTile> { + public int compare(FieldPapersTile s1, FieldPapersTile s2) { + long t1 = s1.access_time(); + long t2 = s2.access_time(); + if (s1 == s2) return 0; + if (t1 == t2) { + t1 = s1.hashCode(); + t2 = s2.hashCode(); + } + if (t1 < t2) return -1; + return 1; + } + } + + long lastCheck = 0; + /** + * <p> + * Check if tiles.size() is not more than max_nr_tiles. If yes, oldest tiles by timestamp + * are fired out from cache. + * </p> + */ + public void checkTileStorage() { + long now = System.currentTimeMillis(); + if (now - lastCheck < 1000) return; + lastCheck = now; + TreeSet<FieldPapersTile> tiles = new TreeSet<FieldPapersTile>(new TileTimeComp()); + tiles.addAll(tileStorage.values()); + int max_nr_tiles = 100; + if (tiles.size() < max_nr_tiles) { + return; + } + int dropCount = tiles.size() - max_nr_tiles;; + for (FieldPapersTile t : tiles) { + if (dropCount <= 0) + break; + t.dropImage(); + dropCount--; + } + } + + void loadSingleTile(FieldPapersTile tile) { + tile.loadImage(); + this.checkTileStorage(); + } + + /* + * Attempt to approximate how much the image is + * being scaled. For instance, a 100x100 image + * being scaled to 50x50 would return 0.25. + */ + Double getImageScaling(Image img, Point p0, Point p1) { + int realWidth = img.getWidth(this); + int realHeight = img.getHeight(this); + if (realWidth == -1 || realHeight == -1) + return null; + int drawWidth = p1.x - p0.x; + int drawHeight = p1.x - p0.x; + + double drawArea = drawWidth * drawHeight; + double realArea = realWidth * realHeight; + + return drawArea / realArea; + } + + /** + */ + @Override + public void paint(Graphics2D g, MapView mv, Bounds bounds) { + LatLon topLeft = mv.getLatLon(0, 0); + LatLon botRight = mv.getLatLon(mv.getWidth(), mv.getHeight()); + Graphics2D oldg = g; + + if (botRight.lon() == 0.0 || botRight.lat() == 0) { + // probably still initializing + return; + } + if (lastTopLeft != null && lastBotRight != null + && topLeft.equalsEpsilon(lastTopLeft) + && botRight.equalsEpsilon(lastBotRight) && bufferImage != null + && mv.getWidth() == bufferImage.getWidth(null) + && mv.getHeight() == bufferImage.getHeight(null) && !needRedraw) { + + g.drawImage(bufferImage, 0, 0, null); + return; + } + + needRedraw = false; + lastTopLeft = topLeft; + lastBotRight = botRight; + bufferImage = mv.createImage(mv.getWidth(), mv.getHeight()); + g = (Graphics2D) bufferImage.getGraphics(); + + if (!LatLon.isValidLat(topLeft.lat()) || + !LatLon.isValidLat(botRight.lat()) || + !LatLon.isValidLon(topLeft.lon()) || + !LatLon.isValidLon(botRight.lon())) + return; + + viewportMinX = lonToTileX(topLeft.lon()); + viewportMaxX = lonToTileX(botRight.lon()); + viewportMinY = latToTileY(topLeft.lat()); + viewportMaxY = latToTileY(botRight.lat()); + + if (viewportMinX > viewportMaxX) { + int tmp = viewportMinX; + viewportMinX = viewportMaxX; + viewportMaxX = tmp; + } + if (viewportMinY > viewportMaxY) { + int tmp = viewportMinY; + viewportMinY = viewportMaxY; + viewportMaxY = tmp; + } + + if (viewportMaxX-viewportMinX > 18) return; + if (viewportMaxY-viewportMinY > 18) return; + + for (int x = viewportMinX - 1; x <= viewportMaxX + 1; x++) { + double lon = tileXToLon(x); + for (int y = viewportMinY - 1; y <= viewportMaxY + 1; y++) { + LatLon tmpLL = new LatLon(tileYToLat(y), lon); + pixelpos[x - viewportMinX + 1][y - viewportMinY + 1] = mv.getPoint(Main.getProjection() + .latlon2eastNorth(tmpLL)); + } + } + + g.setColor(Color.DARK_GRAY); + + Double imageScale = null; + int count = 0; + + for (int x = viewportMinX-1; x <= viewportMaxX; x++) { + + for (int y = viewportMinY-1; y <= viewportMaxY; y++) { + FieldPapersKey key = new FieldPapersKey(currentZoomLevel, x, y); + FieldPapersTile tile; + tile = tileStorage.get(key); + if (!key.valid) continue; + if (tile == null) { + // check if tile is in range + Bounds tileBounds = new Bounds(new LatLon(tileYToLat(y+1), tileXToLon(x)), + new LatLon(tileYToLat(y), tileXToLon(x+1))); + if (!tileBounds.asRect().intersects(printBounds.asRect())) continue; + tile = new FieldPapersTile(x, y, currentZoomLevel, this); + tileStorage.put(key, tile); + loadSingleTile(tile); + checkTileStorage(); + } + Image img = tile.getImage(); + + if (img != null) { + Point p = pixelpos[x - viewportMinX + 1][y - viewportMinY + 1]; + Point p2 = pixelpos[x - viewportMinX + 2][y - viewportMinY + 2]; + g.drawImage(img, p.x, p.y, p2.x - p.x, p2.y - p.y, this); + if (imageScale == null) + imageScale = getImageScaling(img, p, p2); + count++; + } + } + } + + if (count == 0) + { + //System.out.println("no images on " + walkingPapersId + ", return"); + return; + } + + oldg.drawImage(bufferImage, 0, 0, null); + + if (imageScale != null) { + // If each source image pixel is being stretched into > 3 + // drawn pixels, zoom in... getting too pixelated + if (imageScale > 3) { + increaseZoomLevel(); + this.paint(oldg, mv, bounds); + } + + // If each source image pixel is being squished into > 0.32 + // of a drawn pixels, zoom out. + else if (imageScale < 0.32) { + decreaseZoomLevel(); + this.paint(oldg, mv, bounds); + } + } + }// end of paint metod + + FieldPapersTile getTileForPixelpos(int px, int py) { + int tilex = viewportMaxX; + int tiley = viewportMaxY; + for (int x = viewportMinX; x <= viewportMaxX; x++) { + if (pixelpos[x - viewportMinX + 1][0].x > px) { + tilex = x - 1; + break; + } + } + + if (tilex == -1) return null; + + for (int y = viewportMinY; y <= viewportMaxY; y++) { + if (pixelpos[0][y - viewportMinY + 1].y > py) { + tiley = y - 1; + break; + } + } + + if (tiley == -1) return null; + + FieldPapersKey key = new FieldPapersKey(currentZoomLevel, tilex, tiley); + if (!key.valid) { + System.err.println("getTileForPixelpos("+px+","+py+") made invalid key"); + return null; + } + FieldPapersTile tile = tileStorage.get(key); + if (tile == null) + tileStorage.put(key, tile = new FieldPapersTile(tilex, tiley, currentZoomLevel, this)); + checkTileStorage(); + return tile; + } + + @Override + public Icon getIcon() { + return ImageProvider.get("walkingpapers"); + } + + @Override + public Object getInfoComponent() { + return getToolTipText(); + } + + @Override + public Action[] getMenuEntries() { + return new Action[] { + LayerListDialog.getInstance().createShowHideLayerAction(), + LayerListDialog.getInstance().createDeleteLayerAction(), + SeparatorLayerAction.INSTANCE, + // color, + // new JMenuItem(new RenameLayerAction(associatedFile, this)), + SeparatorLayerAction.INSTANCE, + new LayerListPopup.InfoAction(this) }; + } + + @Override + public String getToolTipText() { + return tr("Walking Papers layer ({0}) in zoom {1}", this.getWalkingPapersId(), currentZoomLevel); + } + + @Override + public boolean isMergable(Layer other) { + return false; + } + + @Override + public void mergeFrom(Layer from) { + } + + @Override + public void visitBoundingBox(BoundingXYVisitor v) { + if (printBounds != null) + v.visit(printBounds); + } + + private int latToTileY(double lat) { + double l = lat / 180 * Math.PI; + double pf = Math.log(Math.tan(l) + (1 / Math.cos(l))); + return (int) (Math.pow(2.0, currentZoomLevel - 1) * (Math.PI - pf) / Math.PI); + } + + private int lonToTileX(double lon) { + return (int) (Math.pow(2.0, currentZoomLevel - 3) * (lon + 180.0) / 45.0); + } + + private double tileYToLat(int y) { + return Math.atan(Math.sinh(Math.PI + - (Math.PI * y / Math.pow(2.0, currentZoomLevel - 1)))) + * 180 / Math.PI; + } + + private double tileXToLon(int x) { + return x * 45.0 / Math.pow(2.0, currentZoomLevel - 3) - 180.0; + } + + public boolean imageUpdate(Image img, int infoflags, int x, int y, + int width, int height) { + boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0); + if ((infoflags & ERROR) != 0) return false; + // Repaint immediately if we are done, otherwise batch up + // repaint requests every 100 milliseconds + needRedraw = true; + Main.map.repaint(done ? 0 : 100); + return !done; + } + + public String getWalkingPapersId() { + return walkingPapersId; + } + + public URL formatImageUrl(int x, int y, int z) { + String urlstr = tileUrlTemplate. + replace("{x}", String.valueOf(x)). + replace("{y}", String.valueOf(y)). + replace("{z}", String.valueOf(z)); + try { + return new URL(urlstr); + } catch (Exception ex) { + return null; + } + } + +} diff --git a/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersPlugin.java b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersPlugin.java new file mode 100644 index 0000000..bfbf7b9 --- /dev/null +++ b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersPlugin.java @@ -0,0 +1,33 @@ +package org.openstreetmap.josm.plugins.fieldpapers; + +import static org.openstreetmap.josm.gui.help.HelpUtil.ht; +import static org.openstreetmap.josm.tools.I18n.marktr; + +import java.awt.event.KeyEvent; + +import javax.swing.JMenu; +import javax.swing.JMenuItem; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.gui.MainMenu; +import org.openstreetmap.josm.plugins.Plugin; +import org.openstreetmap.josm.plugins.PluginInformation; + +/** + * Main class for the walking papers plugin. + * + * @author Frederik Ramm <frederik@remote.org> + * + */ +public class FieldPapersPlugin extends Plugin +{ + static JMenu walkingPapersMenu; + + public FieldPapersPlugin(PluginInformation info) + { + super(info); + MainMenu menu = Main.main.menu; + walkingPapersMenu = menu.addMenu(marktr("Walking Papers"), KeyEvent.VK_K, menu.defaultMenuPos, ht("/Plugin/WalkingPapers")); + walkingPapersMenu.add(new JMenuItem(new FieldPapersAddLayerAction())); + } +} diff --git a/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersTile.java b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersTile.java new file mode 100644 index 0000000..9679e03 --- /dev/null +++ b/src/org/openstreetmap/josm/plugins/fieldpapers/FieldPapersTile.java @@ -0,0 +1,67 @@ +package org.openstreetmap.josm.plugins.fieldpapers; + +import java.awt.Image; +import java.awt.Toolkit; +import java.net.URL; + +/** + * Class that contains information about one single slippy map tile. + * + * @author Frederik Ramm <frederik@remote.org> + * @author LuVar <lubomir.varga@freemap.sk> + * @author Dave Hansen <dave@sr71.net> + * + */ +public class FieldPapersTile { + private Image tileImage; + long timestamp; + + int x; + int y; + int z; + + FieldPapersLayer parentLayer; + + + public FieldPapersTile(int x, int y, int z, FieldPapersLayer parent) { + this.x = x; + this.y = y; + this.z = z; + parentLayer = parent; + timestamp = System.currentTimeMillis(); + } + + public URL getImageUrl() { + return parentLayer.formatImageUrl(x, y, z); + } + + public void loadImage() { + URL imageUrl = this.getImageUrl(); + tileImage = Toolkit.getDefaultToolkit().createImage(imageUrl); + Toolkit.getDefaultToolkit().sync(); + timestamp = System.currentTimeMillis(); + } + + public Image getImage() { + timestamp = System.currentTimeMillis(); + return tileImage; + } + + public void dropImage() { + tileImage = null; + // This should work in theory but doesn't seem to actually + // reduce the X server memory usage + //tileImage.flush(); + } + + public long access_time() { + return timestamp; + } + + public boolean equals(Object o) { + if (!(o instanceof FieldPapersTile)) + return false; + FieldPapersTile other = (FieldPapersTile) o; + return (this.x == other.x && this.y == other.y && this.z == other.z); + } +}