diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index 20cb764861..3b14ccda56 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -7,7 +7,7 @@ - + @@ -52,7 +52,7 @@ @@ -66,7 +66,7 @@ - label { - flex: 1; -} -.form-row > input { - flex: 1; - width: auto; -} -.form-row > button { - flex: 1; -} - -th, td { - text-align: left; - padding: 8px; -} - -tr:nth-child(even){background-color: #f2f2f2} -tr:hover {background-color: #d5d5d5;} - -th { - background-color: #4CAF50; - color: white; -} -.loader, -.loader:before, -.loader:after { - border-radius: 50%; - width: 2.5em; - height: 2.5em; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; - -webkit-animation: load7 1.8s infinite ease-in-out; - animation: load7 1.8s infinite ease-in-out; -} -.loader { - color: #00ffff; - font-size: 10px; - margin: 25px auto; - position: relative; - text-indent: -9999em; - -webkit-transform: translateZ(0); - -ms-transform: translateZ(0); - transform: translateZ(0); - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; -} -.loader:before, -.loader:after { - content: ''; - position: absolute; - top: 0; -} -.loader:before { - left: -3.5em; - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; -} -.loader:after { - left: 3.5em; -} -@-webkit-keyframes load7 { - 0%, - 80%, - 100% { - box-shadow: 0 2.5em 0 -1.3em; - } - 40% { - box-shadow: 0 2.5em 0 0; - } -} -@keyframes load7 { - 0%, - 80%, - 100% { - box-shadow: 0 2.5em 0 -1.3em; - } - 40% { - box-shadow: 0 2.5em 0 0; - } -} \ No newline at end of file diff --git a/OsmAnd/assets/server/scripts/blog.js b/OsmAnd/assets/server/scripts/blog.js deleted file mode 100644 index 34b2ab20a2..0000000000 --- a/OsmAnd/assets/server/scripts/blog.js +++ /dev/null @@ -1,86 +0,0 @@ -var blogArticles = [ - {title:'OsmAnd for iPhone is released', url:'blog.html?id=osmand-ios', id:'osmand-ios', gatag:'osmand_ios'}, - {title:'Nautical charts', url:'blog.html?id=nautical-charts', id:'nautical-charts', gatag:'nautical_charts'}, - {title:'OsmAnd DVR goes live', url:'blog.html?id=osmand-dvr-goes-live', id:'osmand-dvr-goes-live', gatag:'osmand_dvr_goes_live'}, - {title:'OsmAnd 1.9', url:'blog.html?id=osmand-1-9-released', id:'osmand-1-9-released', gatag:'osmand_1_9'}, - {title:'OsmAnd 1.8', url:'blog.html?id=osmand-1-8-released', id:'osmand-1-8-released', gatag:'osmand_1_8'}, - {title:'OsmAnd 1.7', url:'blog.html?id=osmand-1-7-released', id:'osmand-1-7-released', gatag:'osmand_1_7'}, - {title:'OsmAnd 1.6 Released', url:'blog.html?id=osmand-1-6-released', id:'osmand-1-6-released', gatag:'osmand_1_6'}, - {title:'OsmAnd 1.5 Released', url:'blog.html?id=osmand-1-5-released', id:'osmand-1-5-released', gatag:'osmand_1_5'} -]; - -var webSiteUrl = "http://osmand.net"; - -$.urlParam = function(url, name){ - var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(url); - if (results==null){ - return null; - } - else{ - return results[1] || 0; - } -} - -function blog(container){ - -var getFullArticleUrl = function(articleObj){ - return webSiteUrl + "/" + articleObj.url; -} - -var fixTwitter =function (){ - $('#___plusone_0 iframe').css('height', '21px'); -} - -var updateMetaTags = function(articleObj){ - if (articleObj && articleObj != null){ - var articleFullUrl = getFullArticleUrl(articleObj); - $('meta[property="og:title"]').attr('content', articleObj.title); - $('meta[property="og:url"]').attr('content', articleFullUrl); - $('meta[property="og:description"]').attr('content', articleObj.title); - - $('link[rel="canonical"]').attr('href', articleFullUrl); - - $('div.fb-like').attr('data-href', articleFullUrl); - $('.twitter-share-button').attr('data-url', articleFullUrl); - } -} - -var getArticleById = function(articleid){ - for(var i=0; i < blogArticles.length;++i){ - if (blogArticles[i].id === articleid){ - return blogArticles[i]; - } - } - return null; -} - -var init = function(){ - container.empty(); - - for(var i=0; i < blogArticles.length; ++i){ - var link = blogArticles[i]; - container.append('
  • ' + link.title + '
  • '); - } - - var articleid = $.urlParam(window.location.href, 'id'); - if (!articleid || articleid == null){ - articleid = blogArticles[0].id; - } - //hide share buttons - $('.share_buttons').css('display', 'none'); - updateMetaTags(getArticleById(articleid)); - var url = 'blog_articles' + '/' + articleid + ".html"; - $( ".article" ).load(url, function( response, status, xhr) { - if ( status != "error" ) { - - $('.share_buttons').css('display', 'block'); - setTimeout(fixTwitter, 5000); - } - }); - -} - -init(); - - -} \ No newline at end of file diff --git a/OsmAnd/assets/server/scripts/poll.js b/OsmAnd/assets/server/scripts/poll.js deleted file mode 100644 index 5227005d7e..0000000000 --- a/OsmAnd/assets/server/scripts/poll.js +++ /dev/null @@ -1,35 +0,0 @@ -function applyPolStyles(){ - - if ($('.pds-box').length > 0){ - $('.pds-box').css('border', 'none'); - $('.pds-vote-button').css('float', 'left'); - $('.pds-vote-button').css('background', 'none'); - $('.pds-vote-button').css('background-color', '#FF8F00'); - $('.pds-vote-button').css('color', '#fff'); - $('.pds-vote-button').css('border', 'none'); - $('.pds-vote-button').css('border-radius', '5px'); - $('.pds-box-outer').css('padding', '0'); - $('.pds-view-results').on('click', function(){ - subscribeToReturnToPoll(); - }); - }else{ - setTimeout(applyPolStyles, timeout); - } - } - - function subscribeToReturnToPoll(){ - if ($('.pds-return-poll').length > 0){ - $('.pds-return-poll').on('click', function(){applyStyleOnBackToPoll();}); - applyPolStyles(); - }else{ - setTimeout(subscribeToReturnToPoll, timeout); - } - } - - function applyStyleOnBackToPoll(){ - if ($('.pds-view-results').length >0){ - applyPolStyles(); - }else{ - setTimeout(applyStyleOnBackToPoll, timeout); - } - } \ No newline at end of file diff --git a/OsmAnd/assets/server/scripts/slider.js b/OsmAnd/assets/server/scripts/slider.js deleted file mode 100644 index cd0adf0695..0000000000 --- a/OsmAnd/assets/server/scripts/slider.js +++ /dev/null @@ -1,129 +0,0 @@ -var images_android=[ -"promo-1s.png", -"promo-2s.png", -"promo-3s.png", -"promo-4s.png", -"promo-5s.png", -"promo-6s.png", -"promo-7s.png", -"promo-8s.png", -"promo-9s.png", -"promo-10s.png", -"promo-11s.png", -"promo-12s.png" -]; - -var images_ios=[ -"ios-1s.png", -"ios-2s.png", -"ios-3s.png", -"ios-4s.png", -"ios-5s.png" -]; - -function slider(container){ -var $cnt = $(container); -var $img1 = $cnt.find("#screenshot1"); -var $img2 =$cnt.find("#screenshot2"); -var $img3 = $cnt.find("#screenshot3"); -var $img4 = $cnt.find("#screenshot4"); -var $leftarrow = $cnt.find(".arrow.left"); -var $rightarrow = $cnt.find(".arrow.right"); -var $btnleft = $cnt.find(".button.left"); -var $btnright = $cnt.find(".button.right"); -var currentPosition =0; -var count =4; - -var images = images_android; - -var init = function(){ - updatePictures(); - updateArrows(); - $leftarrow.on('click', function(){ - if (currentPosition > 0){ - currentPosition-=count; - updatePictures(); - updateArrows(); - } - }); - $rightarrow.on('click', function(){ - if (currentPosition + count < images.length){ - currentPosition+=count; - updatePictures(); - updateArrows(); - } - }); - $btnleft.on('click', function(){ - if (!$btnleft.hasClass("active")){ - $btnleft.addClass("active"); - $btnright.removeClass("active"); - $btnright.addClass - images = images_android; - currentPosition = 0; - updatePictures(); - updateArrows(); - } - - - }); - $btnright.on('click', function(){ - if (!$btnright.hasClass("active")){ - $btnright.addClass("active"); - $btnleft.removeClass("active"); - images = images_ios; - currentPosition = 0; - updatePictures(); - updateArrows(); - } - - }); -} - -var changePicture = function(img, index){ - if (index < images.length){ - img.attr("src", "images/" + images[index]); - }else{ - img.attr("src", "images/empty.png"); - } -} -var updatePictures = function(){ - changePicture( $img1, currentPosition); - changePicture( $img2, currentPosition+1); - changePicture( $img3, currentPosition+2); - changePicture( $img4, currentPosition+3); -} -var updateArrows = function(){ - if (currentPosition + count < images.length){ - enableRightArrow(); - }else{ - disableRightArrow(); - } - if (currentPosition== 0 ){ - disableLeftArrow(); - }else{ - enableLeftArrow(); - } -} -var enableLeftArrow = function(){ - $leftarrow.attr("src", "images/left_arrow_orange.png"); - while ($leftarrow.hasClass("disabled")){ - $leftarrow.removeClass("disabled"); - } -} -var disableLeftArrow = function(){ - $leftarrow.attr("src", "images/left_arrow_grey.png"); - $leftarrow.addClass("disabled"); -} -var enableRightArrow = function(){ - $rightarrow.attr("src", "images/right_arrow_orange.png"); - while ($rightarrow.hasClass("disabled")){ - $rightarrow.removeClass("disabled"); - } -} -var disableRightArrow = function(){ - $rightarrow.attr("src", "images/right_arrow_grey.png"); - $rightarrow.addClass("disabled"); -} -init(); - -} diff --git a/OsmAnd/src/net/osmand/plus/server/IMapOnImageDrawn.java b/OsmAnd/src/net/osmand/plus/server/IMapOnImageDrawn.java new file mode 100644 index 0000000000..573723a5c6 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/server/IMapOnImageDrawn.java @@ -0,0 +1,8 @@ +package net.osmand.plus.server; + +import android.graphics.Bitmap; +import net.osmand.data.RotatedTileBox; + +public interface IMapOnImageDrawn { + void onDraw(RotatedTileBox viewport, Bitmap bmp); +} diff --git a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java index 7e754661d7..758a90b41f 100644 --- a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java +++ b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java @@ -1,10 +1,14 @@ package net.osmand.plus.server; +import android.graphics.Bitmap; import android.util.Log; import android.webkit.MimeTypeMap; +import androidx.fragment.app.FragmentActivity; import fi.iki.elonen.NanoHTTPD; import net.osmand.PlatformUtil; +import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.server.endpoints.TileEndpoint; import java.io.IOException; @@ -12,13 +16,14 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; -public class OsmAndHttpServer extends NanoHTTPD { +public class OsmAndHttpServer extends NanoHTTPD{ private static final String FOLDER_NAME = "server"; private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class); public static final int PORT = 24990; public static String HOSTNAME = "0.0.0.0"; private final Map endpoints = new HashMap<>(); private OsmandApplication application; + private MapActivity mapActivity; public OsmAndHttpServer() throws IOException { super(HOSTNAME, PORT); @@ -72,7 +77,7 @@ public class OsmAndHttpServer extends NanoHTTPD { } private void registerEndpoints() { - register("/tile", new TileEndpoint(application)); + register("/tile", new TileEndpoint(application,mapActivity)); } private void register(String path, ApiEndpoint endpoint) { @@ -95,6 +100,7 @@ public class OsmAndHttpServer extends NanoHTTPD { is, is.available()); } catch (IOException e) { + LOG.error(e); return ErrorResponses.response404; } } @@ -111,6 +117,17 @@ public class OsmAndHttpServer extends NanoHTTPD { return type; } + public void setActivity(FragmentActivity activity) { + if (activity instanceof MapActivity){ + this.mapActivity = (MapActivity)activity; + } + for (String endpoint : endpoints.keySet()){ + if (endpoints.get(endpoint) instanceof TileEndpoint){ + ((TileEndpoint) endpoints.get(endpoint)).setMapActivity(mapActivity); + } + } + } + public static class ErrorResponses { public static NanoHTTPD.Response response404 = newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND, diff --git a/OsmAnd/src/net/osmand/plus/server/ServerFragment.java b/OsmAnd/src/net/osmand/plus/server/ServerFragment.java index 2b0f9423de..9c1f877c85 100644 --- a/OsmAnd/src/net/osmand/plus/server/ServerFragment.java +++ b/OsmAnd/src/net/osmand/plus/server/ServerFragment.java @@ -12,15 +12,18 @@ import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.base.BaseOsmAndFragment; +import org.apache.commons.logging.Log; import java.io.IOException; import static android.content.Context.WIFI_SERVICE; public class ServerFragment extends BaseOsmAndFragment { + private final static Log LOG = PlatformUtil.getLog(ServerFragment.class); private boolean initialized = false; private OsmAndHttpServer server; private View view; @@ -85,13 +88,14 @@ public class ServerFragment extends BaseOsmAndFragment { try { server = new OsmAndHttpServer(); server.setApplication((OsmandApplication) getMyApplication()); + server.setActivity(this.getActivity()); initialized = true; updateTextView("Server started at: http://" + getDeviceAddress() + ":" + OsmAndHttpServer.PORT); } catch (IOException e) { Toast.makeText(requireContext(), e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); - e.printStackTrace(); + LOG.error(e); } } diff --git a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java index 74e0453b2e..9a448ce5d6 100644 --- a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java @@ -1,15 +1,19 @@ package net.osmand.plus.server.endpoints; import android.graphics.Bitmap; -import android.util.Log; +import androidx.fragment.app.FragmentActivity; import fi.iki.elonen.NanoHTTPD; import net.osmand.PlatformUtil; import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.render.MapRenderRepositories; import net.osmand.plus.resources.AsyncLoadingThread; import net.osmand.plus.server.ApiEndpoint; +import net.osmand.plus.server.IMapOnImageDrawn; import net.osmand.plus.server.OsmAndHttpServer; +import net.osmand.plus.server.ServerFragment; +import org.apache.commons.logging.Log; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -20,21 +24,33 @@ import java.util.Scanner; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; -public class TileEndpoint implements ApiEndpoint { +public class TileEndpoint implements ApiEndpoint, IMapOnImageDrawn { private static final int RENDER_WAIT_THRESHOLD = 5000; private static final Object lock = new Object(); private static final int TILE_SIZE_PX = 512; + private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); Map hashMap = new HashMap<>(); Map map = Collections.synchronizedMap(hashMap); OsmandApplication application; + private RotatedTileBox viewPort; + private Bitmap resultBitmap; + private MapActivity mapActivity; - public TileEndpoint(OsmandApplication application) { + @Override + public void onDraw(RotatedTileBox viewport, Bitmap bmp) { + map.put(viewport, bmp); + } + + public TileEndpoint(OsmandApplication application, MapActivity mapActivity) { this.application = application; + this.mapActivity = mapActivity; } @Override public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { synchronized (lock) { + this.mapActivity.getMapView().setOnImageDrawnListener(this); + RotatedTileBox tileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); int zoom; double lat; double lon; @@ -52,6 +68,7 @@ public class TileEndpoint implements ApiEndpoint { bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); ByteArrayInputStream str = new ByteArrayInputStream(byteArray); + mapActivity.getMapView().setCurrentViewport(tileBoxCopy); return newFixedLengthResponse( NanoHTTPD.Response.Status.OK, "image/png", @@ -65,25 +82,42 @@ public class TileEndpoint implements ApiEndpoint { this.application = application; } + public void setMapActivity(MapActivity mapActivity) { + this.mapActivity = mapActivity; + } + private Bitmap requestTile(double lat, double lon, int zoom) { final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder() .setLocation(lat, lon) .setZoom(zoom) .setPixelDimensions(TILE_SIZE_PX, TILE_SIZE_PX, 0.5f, 0.5f).build(); final MapRenderRepositories renderer = application.getResourceManager().getRenderer(); - application.getResourceManager().updateRendererMap(rotatedTileBox, new AsyncLoadingThread.OnMapLoadedListener() { - @Override - public void onMapLoaded(boolean interrupted) { - map.put(rotatedTileBox, renderer.getBitmap()); - } - }); - Bitmap bmp; + mapActivity.getMapView().setCurrentViewport(rotatedTileBox); +// application.getResourceManager().updateRendererMap(rotatedTileBox, new AsyncLoadingThread.OnMapLoadedListener() { +// @Override +// public void onMapLoaded(boolean interrupted) { +// map.put(rotatedTileBox, renderer.getBitmap()); +// } +// }); + Bitmap bmp = null; int sleepTime = 500; + int timeout = 0; + + +// try { +// while ((viewPort == null && !rotatedTileBox.equals(viewPort)) || timeout < 5000) { +// Thread.sleep(100); +// timeout += 100; +// } +// return resultBitmap; +// } catch (InterruptedException e) { +// LOG.error(e); +// } while ((bmp = map.get(rotatedTileBox)) == null) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { - e.printStackTrace(); + LOG.error(e); } sleepTime += 500; if (sleepTime > RENDER_WAIT_THRESHOLD) { diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index 260f30fa50..16742389be 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -46,6 +46,8 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.TwoFingerTapDetector; +import net.osmand.plus.server.IMapOnImageDrawn; +import net.osmand.plus.server.endpoints.TileEndpoint; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; @@ -77,6 +79,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback { protected OsmandSettings settings = null; private CanvasColors canvasColors = null; private Boolean nightMode = null; + private IMapOnImageDrawn mapOnImageDrawnListener; private class CanvasColors { int colorDay = MAP_DEFAULT_COLOR; @@ -86,7 +89,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback { private class FPSMeasurement { int fpsMeasureCount = 0; int fpsMeasureMs = 0; - long fpsFirstMeasurement = 0; + long fpsFirstMeasurement = 0 ; float fps; void calculateFPS(long start, long end) { @@ -341,6 +344,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback { return application; } + public void setOnImageDrawnListener(IMapOnImageDrawn iMapOnImageDrawn) { + this.mapOnImageDrawnListener = iMapOnImageDrawn; + } + // ///////////////////////// NON UI PART (could be extracted in common) ///////////////////////////// public LatLon getFirstTouchPointLatLon() { return firstTouchPointLatLon; @@ -574,6 +581,9 @@ public class OsmandMapTileView implements IMapDownloaderCallback { if (!bufferBitmap.isRecycled()) { RectF rct = new RectF(x1, y1, x2, y2); canvas.drawBitmap(bufferBitmap, null, rct, paintImg); + if (mapOnImageDrawnListener != null){ + mapOnImageDrawnListener.onDraw(currentViewport,bufferBitmap); + } } canvas.rotate(-rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY()); } @@ -869,6 +879,11 @@ public class OsmandMapTileView implements IMapDownloaderCallback { return currentViewport; } + public void setCurrentViewport(RotatedTileBox viewport) { + currentViewport = viewport; + refreshMap(); + } + public float getDensity() { return currentViewport.getDensity(); }