OSMDroid - how to set two tile source? - java

I trying to implement OSM using osmdroid, so far i am able to do everything correctly. But i would like to know how i can set two tile sources on top of each other.
Below is how i am trying to implement :
map = (MapView) findViewById(R.id.map);
map.getTileProvider().getTileCache().getProtectedTileComputers().clear();
map.getTileProvider().getTileCache().setAutoEnsureCapacity(false);
map.setTileSource(TileSourceFactory.MAPNIK);
map.setTileSource(new OnlineTileSourceBase("USGS Topo", 0, 18, 256, ".png?apikey=123",
new String[] { "https://api.xyz.com/maps/satellite/zxy/2020-04-21T16:10:00Z/" }) {
#Override
public String getTileURLString(long pMapTileIndex) {
return getBaseUrl()
+ MapTileIndex.getZoom(pMapTileIndex)
+ "/" + MapTileIndex.getY(pMapTileIndex)
+ "/" + MapTileIndex.getX(pMapTileIndex)
+ mImageFilenameEnding;
}
});
map.setVerticalMapRepetitionEnabled(false);
So far i am getting below output but there is no mapnik source under the satellite tile source.
but i need the output to look like this
How do i achieve this ?

As mentioned in the wiki docs on osmdroid's GitHub page, you can use more than one tile source at a time.
You can only set one setTileSource, so for your code to work you need to set the map as the tile source and add the weather tile layer as an overlay over it.
map = (MapView) findViewById(R.id.map);
map.getTileProvider().getTileCache().getProtectedTileComputers().clear();
map.getTileProvider().getTileCache().setAutoEnsureCapacity(false);
map.setTileSource(TileSourceFactory.MAPNIK);
MapTileProviderBasic provider = new MapTileProviderBasic(MainActivity.this, new OnlineTileSourceBase("USGS Topo", 0, 18, 256, "png?apikey=123", new String[0]) {
#Override
public String getTileURLString(MapTile aTile) {
// BoundingBox bbox = tile2boundingBox(aTile.getX(), aTile.getY(), aTile.getZoomLevel());
// String baseUrl ="https://api.xyz.com/maps/satellite/zxy/2020-04-21T16:10:00Z/?dpi=96&transparent=true&format=png24&bbox="+bbox.west+","+bbox.south+","+bbox.east+","+bbox.north+"&size=256,256&f=image";
return "https://api.xyz.com/maps/satellite/zxy/2020-04-21T16:10:00Z/" + aTile.getZoomLevel() + "/" + aTile.getY() + "/" + aTile.getX();
// return baseUrl;
}
});
TilesOverlay layer = new TilesOverlay(provider, MainActivity.this);
layer.setLoadingBackgroundColor(Color.TRANSPARENT);
layer.setLoadingLineColor(Color.TRANSPARENT);
map.getOverlays().add(layer);
map.setVerticalMapRepetitionEnabled(false);
If you are using osmndroid-wms then too you can use a map layer and an overlay layer on it by changing the following line
MapTileProviderBasic provider = new MapTileProviderBasic(MainActivity.this, mWMSTileSource)
over here mWMSTileSource will be the response you get from WMSTileSource.createFrom(WMSEndpoint endpoint, WMSLayer layer) after you have made a call to the WMS server as mentioned in the wiki.

Related

How to read all google adwords targeting options using AWQL or Selectors?

For example, I want to read Age Ranges, Genders, Operating Systems, etc, which are supported in google adwords. I want to read the above said targeting options using either AWQL or Selector?
I am able to read those targeting options using ConstantDataService.
AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();
ConstantDataServiceInterface constantDataService =
adWordsServices.get(this.session, ConstantDataServiceInterface.class);
AgeRange []ageRanges = constantDataService.getAgeRangeCriterion();
for(AgeRange a : ageRanges) {
System.out.println(a.getId() + " :: " + a.getAgeRangeType() + " :: " + a.getCriterionType() + " :: " + a.getType());
}
But I am unable to apply filters. I saw that I can apply filters if I use AWQL or Selector? I tried the following
AdGroupCriterionServiceInterface adGroupCriterionService =
adWordsServices.get(session, AdGroupCriterionServiceInterface.class);
// Create selector.
SelectorBuilder builder = new SelectorBuilder();
Selector selector = builder
.fields("Id", "AgeRangeType")
.build();
int PAGE_SIZE = 100;
ServiceQuery serviceQuery = new ServiceQuery.Builder().fields(AdGroupCriterionField.Id, AdGroupCriterionField.AgeRangeType).limit(0, PAGE_SIZE).build();
// Set selector paging = the most important change is to set numberResults to 0.
AdGroupCriterionPage page = null;
do {
serviceQuery.nextPage(page);
page = adGroupCriterionService.query(serviceQuery.toString());
if (page.getEntries() != null) {
for (AdGroupCriterion criterion : page.getEntries()) {
System.out.printf("Campaign with name '%s' and ID %d was found.%n", criterion.getAdGroupCriterionType(),
criterion.getCriterion());
}
} else {
System.out.println("No criterion were found.");
}
} while(serviceQuery.hasNext(page));
but not working as expected.
Can someone tell me how to read targeting options using AWQL or Selector?

Feature Layer is getting null bounds with featurecollection derived from RasterToVectorProcess

Null Pinter Exception simply means that it is because of value is getting null. But In case of using APis such as GeoTiff it becomes annoying to find out the error in usage.
My code is as follows:
System.out.println("vectorization starts");
GridCoverage2D srcCoverage = new GeoTiffReader(new File("E:/output/ll_processed.TIFF")).read(new GeneralParameterValue[]{policy, gridsize, useJaiRead});
SimpleFeatureCollection fc = RasterToVectorProcess.process(srcCoverage, 3, cov.getEnvelope(), Collections.singletonList(0.0d), true, null);
System.out.println("process ends");
System.out.println("vectorization ends");
//MapContext map = new DefaultMapContext();
//map.setTitle("raster to vector conversion");
Style style = SLD.createPolygonStyle(Color.BLUE, Color.CYAN, 1.0f);
//map.addLayer(fc, style);
//map.getLayerBounds();
//JMapFrame.showMap(map);
MapContent mapContent= new MapContent();
mapContent.setTitle("Illegal Mining");
Layer layer = new FeatureLayer(fc, style,"VectorLayer");
//int boundary = 10;
// ReferencedEnvelope env2 = new ReferencedEnvelope(srcCoverage.getEnvelope().getMinimum(0) - boundary, srcCoverage.getEnvelope().getMaximum(0) + boundary,
//srcCoverage.getEnvelope().getMinimum(1) - boundary, srcCoverage.getEnvelope().getMaximum(1) + boundary, srcCoverage.getCoordinateReferenceSystem());
//mapContent.getViewport().setBounds(fc.getBounds());
Line 199 : if(layer.getBounds()!=null) // here the error is coming also tried with if(layer != null && layer.getBounds()!=null)
{
mapContent.addLayer(layer);
}else{
System.out.println("Layer bounds are null");
}
mapContent.getViewport().setCoordinateReferenceSystem(
DefaultGeographicCRS.WGS84);
Error
at org.geotools.map.FeatureLayer.getBounds(FeatureLayer.java:199)
I am trying to convert Tiff to Vector image and Then I want to store it on disk.
Most likely, your featureSource is null, since the geotools FeatureLayer class method getBounds() uses the featureSource to retrieve the bounds, but in the constructor FeatureLayer doesn't check whether the featureSource is null.
The featureSource is the first argument to the constructor of FeatureLayer. In your case, that's variable SimpleFeatureCollection fc.
Most likely, the method process.process returned null so fc is null.
Minor Change in RasterToVectorProcess.java
//features.add(builder.buildFeature(null));
//System.out.println("ignored");
//add
System.out.println("adding...");
SimpleFeature feature = builder.buildFeature(null);
((Collection<SimpleFeature>) features).add(feature);

download cover art from musicbrainz with java

I am struggling for a couple of hours now on how to link a discid to a musicbrainz mbid.
So, using dietmar-steiner / JMBDiscId
JMBDiscId discId = new JMBDiscId();
if (discId.init(PropertyFinder.getProperty("libdiscid.path")))
{
String musicBrainzDiscID = discId.getDiscId(PropertyFinder.getProperty("cdrom.path"));
}
or musicbrainzws2-java
Disc controller = new Disc();
String drive = PropertyFinder.getProperty("cdrom.path");
try {
DiscWs2 disc =controller.lookUp(drive);
log.info("DISC: " + disc.getDiscId() + " match: " + disc.getReleases().size() + " releases");
....
I can extract a discid for freedb or musicbrainz easily (more or less), but I have not found a way on calculating the id I that I need to download cover art via the CoverArtArchiveClient from last.fm.
CoverArtArchiveClient client = new DefaultCoverArtArchiveClient();
try
{
UUID mbid = UUID.fromString("mbid to locate release");
fm.last.musicbrainz.coverart.CoverArt coverArt = client.getByMbid(mbid);
Theoretically, I assume, I could you the data collected by musicbrainzws2-java to trigger a search, and then use the mbid from the result ... but that cannot be the best option to do.
I am happy about any push into the right direction...
Cheers,
Ed.
You don't calculate the MBID. The MBID is attached on every entity you retrieve from MusicBrainz.
When getting releases by DiscID you get a list. Each entry is a release and has an MBID, accessible with getId():
for (ReleaseWs2 rel : disc.getReleases()){
log.info("MBID: " + rel.getId() + ", String: " + rel.toString());
}
You then probably want to try the CoverArtArchive (CAA) for every release and take the first cover art you get.
Unfortunately I don't know of any API documentation for musicbrainzws2 on the web. I recommend running javadoc on all source files.

Apache Commons - NNTP - "Article To List" - AWT

I am currently using Apache Commons Net to develop my own NNTP reader. Using the tutorial available I was able to use some of their code to allow me to get articles back.
The Code I am using from NNTP Section -
System.out.println("Retrieving articles between [" + lowArticleNumber + "] and [" + highArticleNumber + "]");
Iterable<Article> articles = client.iterateArticleInfo(lowArticleNumber, highArticleNumber);
System.out.println("Building message thread tree...");
Threader threader = new Threader();
Article root = (Article)threader.thread(articles);
Article.printThread(root, 0);
I need to take the articles and turn them into a List type so I can send them to AWT using something like this -
List x = (List) b.GetGroupList(dog);
f.add(CreateList(x));
My Entire code Base for this section is -
public void GetThreadList(String Search) throws SocketException, IOException {
String hostname = USE_NET_HOST;
String newsgroup = Search;
NNTPClient client = new NNTPClient();
client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
client.connect(hostname);
client.authenticate(USER_NAME, PASS_WORD);
if(!client.authenticate(USER_NAME, PASS_WORD)) {
System.out.println("Authentication failed for user " + USER_NAME + "!");
System.exit(1);
}
String fmt[] = client.listOverviewFmt();
if (fmt != null) {
System.out.println("LIST OVERVIEW.FMT:");
for(String s : fmt) {
System.out.println(s);
}
} else {
System.out.println("Failed to get OVERVIEW.FMT");
}
NewsgroupInfo group = new NewsgroupInfo();
client.selectNewsgroup(newsgroup, group);
long lowArticleNumber = group.getFirstArticleLong();
long highArticleNumber = lowArticleNumber + 5000;
System.out.println("Retrieving articles between [" + lowArticleNumber + "] and [" + highArticleNumber + "]");
Iterable<Article> articles = client.iterateArticleInfo(lowArticleNumber, highArticleNumber);
System.out.println("Building message thread tree...");
Threader threader = new Threader();
Article root = (Article)threader.thread(articles);
Article.printThread(root, 0);
try {
if (client.isConnected()) {
client.disconnect();
}
}
catch (IOException e) {
System.err.println("Error disconnecting from server.");
e.printStackTrace();
}
}
and -
public void CreateFrame() throws SocketException, IOException {
// Make a new program view
Frame f = new Frame("NNTP Reader");
// Pick my layout
f.setLayout(new GridLayout());
// Set the size
f.setSize(H_SIZE, V_SIZE);
// Make it resizable
f.setResizable(true);
//Create the menubar
f.setMenuBar(CreateMenu());
// Create the lists
UseNetController b = new UseNetController(NEWS_SERVER_CREDS);
String dog = "*";
List x = (List) b.GetGroupList(dog);
f.add(CreateList(x));
//f.add(CreateList(y));
// Add Listeners
f = CreateListeners(f);
// Show the program
f.setVisible(true);
}
I just want to take my list of returned news articles and send them to the display in AWT. Can any one explain to me how to turn those Articles into a list?
Welcome to the DIY newsreader club. I'm not sure if you are trying to get a list of newsgroups on the server, or articles.You have already have your Articles in an Iterable Collection. Iterate through it appending what you want in the list from each article. You probably aren't going to want to display the whole article body in a list view. More likely the message id, subject, author or date (or combination as a string). For example for a List of just subjects:
...
Iterable<Article> articles = client.iterateArticleInfo(lowArticleNumber, highArticleNumber);
Iterator<Article> it = articles.iterator();
while(it.hasNext()) {
Article thisone = it.next();
MyList.add(thisone.getSubject());
//MyList should have been declared up there somewhere ^^^ and
//your GetThreadList method must include List in the declaration
}
return MyList;
...
My strategy has been to retrieve the articles via an iterator in to an SQLite database with the body, subject, references etc. stored in fields. Then you can create a list sorted just how you want, with a link by primary key to retrieve what you need for individual articles as you display them. Another strategy would be an array of message_ids or article numbers and fetch each one individually from the news server as required. Have fun - particularly when you are coding for Android and want to display a list of threaded messages in the correct sequence with suitable indents and markers ;). In fact, you can learn a lot by looking at the open source Groundhog newsreader project (to which I am eternally grateful).
http://bazaar.launchpad.net/~juanjux/groundhog/trunk/files/head:/GroundhogReader/src/com/almarsoft/GroundhogReader

DJ Native Swing javascript command problems

Using DJ Native Swing it is possible to show a web page within a java application. When you do this it is also possible to communicate from the browser to the java runtime environment using the "command" protocol. The documentation has a code snippet which demonstrates it's usage:
function sendCommand( command ){
var s = 'command://' + encodeURIComponent( command );
for( var i = 1; i < arguments.length; s+= '&' + encodeURIComponent( arguments[i++] ) );
window.location = s;
}
As it looks here it seems to be a regular GET request to an url using the command protocol instead of http. Although when I create and image, script tag or just and ajax get request there is no response and the breakpoint in the java runtime isn't triggered.
I don't want to set the window.location because I don't want to navigate away from the page I am currently at. Using the link to navigate to a command url does work though but it also navigates away from the current page. The page uses OpenLayers and dojo. (I have also tried dojo.io.script)
After some work I have found a neat way to communicate with the java runtime which doesn't trigger a refresh of the page every time there is communication. It is inspired on the way JSONP works to get around the cross domain restriction in most browsers these days. Because an iFrame will also trigger a command:// url it possible to do a JSONP like action using this technique. The code on the client side (browser):
dojo.provide( "nmpo.io.java" );
dojo.require( "dojo.io.script" );
nmpo.io.java = dojo.delegate( dojo.io.script, {
attach: function(/*String*/id, /*String*/url, /*Document?*/frameDocument){
// summary:
// creates a new tag pointing to the specified URL and
// adds it to the document.
// description:
// Attaches the script element to the DOM. Use this method if you
// just want to attach a script to the DOM and do not care when or
// if it loads.
var frame = dojo.create( "iframe", {
id: id,
frameborder: 0,
framespacing: 0
}, dojo.body( ) );
dojo.style( frame, { display: "none" } );
dojo.attr( frame, { src: url } );
return frame;
},
_makeScriptDeferred: function(/*Object*/args){
//summary:
// sets up a Deferred object for an IO request.
var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
var ioArgs = dfd.ioArgs;
ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
ioArgs.canDelete = false;
//Special setup for jsonp case
ioArgs.jsonp = args.callbackParamName || args.jsonp;
if(ioArgs.jsonp){
//Add the jsonp parameter.
ioArgs.query = ioArgs.query || "";
if(ioArgs.query.length > 0){
ioArgs.query += "&";
}
ioArgs.query += ioArgs.jsonp
+ "="
+ (args.frameDoc ? "parent." : "")
+ "nmpo.io.java.jsonp_" + ioArgs.id + "._jsonpCallback";
ioArgs.frameDoc = args.frameDoc;
//Setup the Deferred to have the jsonp callback.
ioArgs.canDelete = true;
dfd._jsonpCallback = this._jsonpCallback;
this["jsonp_" + ioArgs.id] = dfd;
}
return dfd; // dojo.Deferred
}
});
When a request is sent to the java runtime a callback argument will be supplied and a webBrowser.executeJavascript( callbackName + "(" + json + ");" ); action can be executed to trigger the callback in the browser.
Usage example client:
dojo.require( "nmpo.io.java" );
nmpo.io.java.get({
// For some reason the first paramater (the one after the '?') is never in the
// paramater array in the java runtime. As a work around we stick in a dummy.
url: "command://sum?_",
callbackParamName: "callback",
content: {
numbers: [ 1, 2, 3, 4, 5 ].join( "," )
},
load: function( result ){
console.log( "A result was returned, the sum was [ " + result.result + " ]" );
}
});
Usage example java:
webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
#Override
public void commandReceived(WebBrowserCommandEvent e) {
// Check if you have the right command here, left out for the example
// Parse the paramaters into a Hashtable or something, also left out for the example
int sum = 0;
for( String number : arguments.get( "numbers" ).split( "," ) ){
sum += Integer.parseInt( number );
}
// Execute the javascript callback like would happen with a regular JSONP call.
webBrowser.executeJavascript( arguments.get( "callback" ) + "({ result: " + sum + " });" );
}
});
Also with IE in the frame I can highly recommend using firebug lite, the dev tools for IE are not available.

Categories