Adding symbol layer with one source removed FillLayer with another source - Mapbox android - google-maps-markers

I have ploygons which I have drawn using FillLayer mapbox which uses a set of GeoJson coordinates to create a source and add to the Fill layer.
After that I am creating another layer (Symbol Layer) this time with a different set of coordinates creating another source object.
When I add Symbol layer,the previously added Fill layer disappears.
I tried multiple solutions but its not working.
Is it even possible to add multiple layers of different types with different source ids?
var bm = BitmapFactory.decodeResource(
resources,
com.mapbox.services.android.navigation.ui.v5.R.drawable.mapbox_marker_icon_default
)
// bm = Bitmap.createScaledBitmap(bm, 80, 80, true);
style.addImage("ID_ICON_AIRPORT", bm)
// Create a SymbolManager.
val symbolManager = SymbolManager(mapView, map, style)
// Set non-data-driven properties.
symbolManager.iconAllowOverlap = true
//symbolManager.iconIgnorePlacement = true
// Create a symbol at the specified location.
val options =
SymbolOptions()
.withLatLng(LatLng(latitude, longitude))
.withIconImage("ID_ICON_AIRPORT")
.withIconSize(1.3f).withTextSize(2f)
symbolManager?.create(options)
symbolManager.addClickListener {
// to open infowindow here
}
I tried with SymbolManager , it works to display the marker but now I don't know how to add info window on the marker click. Expected to see both symbol layer and fill layer, I want symbol layer on top of fill layer.

Related

createGraphics in Instance Mode in p5js

I'm new to p5.
My aim is to display ASCII value of the key I type and also leave a trail of vertical lines whose distance from left is 200+the ASCII value of the key,
which can be done using createGraphics() (adding an additional canvas layer on top with same dimensions as original and drawing on that additional canvas layer)
But the code doesn't seem to work and also it is not displaying any errors in the console.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
};
};
The first issue is that you have to tell the engine that the thing you name p is actually a p5 instance. You can construct a p5 object using new p5(...) as follows:
const c5 = new p5(function(p) {
p.setup = function(){
...
};
p.draw = function(){
...
};
});
You then correctly fill up your pg graphic object with vertical lines. However, you do not "draw" it on your original canvas. You can do so using the p5.js image() function (see also the example shown in the createGraphics() documentation).
I've made a working example in the p5.js editor here.
Your code is very close. You are creating the graphic object and drawing to it but you also need to display it as an image to your canvas. In your code snippet you are also missing the call to create the new p5js object but that may be just a copy paste error.
Here is a working snippet of your code with the call to draw the image. I also moved the key detection logic to keyPressed so the logic only runs when a key is pressed.
Also notice that running the logic inside of keyPressed allows the sketch to handle keys such as f5 by returning false and preventing default behavior. In a real application we would need to be very careful about overriding default behavior. Here we assume that the user wants to know the key code of the f5 key and will be ok with the page not reloading. In a real application that might not be the case.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
};
p.keyPressed = function() {
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.key + " " +p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
p.image(pg, 0, 0);
return false; // prevent default
}
};
var myp5 = new p5(c5)
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>

PDFClown Copy annotations and then manipulate them

I have the need to copy annotations from one PDF File to another. I have used the excellent PDFClown library but unable to manipulate things like color,rotation etc. Is this possible? I can see the baseobject information but also unsure how to manipulate that directly.
I can copy the appearance via cloning appearance but can't "edit" it.
Thanks in advance.
Alex
P.S If Stephano the author is listeing ,is project dead?
On annotations in general and Callout annotations in particular
I looked into it a bit, and I'm afraid there is not much you can deterministically manipulate for arbitrary inputs using high level methods. The reason is that there are numerous alternative ways to set the appearance of a Callout annotation and PDF Clown only supports the less prioritized ways with explicit high level methods. From high priority downwards
An explicit appearance in an AP stream. If it is given, it is used, ignoring whether this appearance looks like a Callout annotation at all, let alone like one defined by the other Callout properties.
PDF Clown does not create an appearance for callout annotations from the other values yet, let alone update existing appearances to follow up to some specific attribute (e.g. Color) change. For ISO 32000-2 support, PDF Clown here will have to improve as appearance streams have become mandatory.
If it exists, you can retrieve the appearance using getAppearance() but you only get a FormXObject with its low level drawing instructions, nothing Callout specific.
One thing you can manipulate quite easily given a FormXObject, though, you can rotate or skew the appearance quite easily by setting its Matrix accordingly, e.g.
annotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100, 10));
A rich text string in the RC string or stream. Unless an appearance is given, the text in the Callout text box is generated from this rich text datum (rich text here uses a XHTML 1.0 subset for formatting).
PDF Clown does not create a rich text representation of the Callout text yet, let alone update existing ones to follow up to some specific attribute (e.g. Color) change..
If it exists, you can retrieve the rich text by low level access using getBaseDataObject().get(PdfName.RC), change this string or stream, and set it again using getBaseDataObject().put(PdfName.RC, ...). Similarly you can retrieve, manipulate, and set the rich text default style string using its name PdfName.DS instead.
A number of different settings for separate aspects used to build the Callout from in the absence of appearance stream and (as far as the text content is concerned) rich text string.
PDF Clown supports (many of) these attributes, in particular if you cast the cloned annotation to StaticNote, e.g. the opacity CA using get/set/withAlpha, the border Border / BS using get/set/withBorder, the background color C using get/set/withColor, ...
It by the way has an error in its line ending style LE support: Apparently the code for the Line annotation LE property was copied without checking; unfortunately that attribute there follows a different syntax...
Your tasks
Concerning the attributes you stated you want to change, therefore,
Rotation: There is no rotation attribute in the Callout annotation per se (other than the flag whether or not to follow the page rotation). Thus, you cannot set a rotation as a simple annotation attribute. If the source annotation does have an appearance stream, though, you can manipulate its Matrix to rotate it inside the annotation rectangle, see above.
Border color and font: If your Callout has an appearance stream, you can try and parse its content using a ContentScanner and manipulate color and font setting operations. Otherwise, if rich text information is set, for the font you can try and parse the rich text using some XML parser and manipulate font style attributes. Otherwise, you can parse the default appearance DA string and manipulate its font and color setting instructions.
Some example code
I created a file with an example Callout annotation using Adobe Acrobat: Callout-Yellow.pdf. It contains an appearance stream, rich text, and simple attributes, so one can use this file for example manipulations at different levels.
The I applied this code to it with different values for keepAppearanceStream and keepRichText (you didn't mention whether you used PDF Clown for Java or .Net; so I chose Java; a port to .Net should be trivial, though...):
boolean keepAppearanceStream = ...;
boolean keepRichText = ...;
try ( InputStream sourceResource = GET_STREAM_FOR("Callout-Yellow.pdf");
InputStream targetResource = GET_STREAM_FOR("test123.pdf");
org.pdfclown.files.File sourceFile = new org.pdfclown.files.File(sourceResource);
org.pdfclown.files.File targetFile = new org.pdfclown.files.File(targetResource); ) {
Document sourceDoc = sourceFile.getDocument();
Page sourcePage = sourceDoc.getPages().get(0);
Annotation<?> sourceAnnotation = sourcePage.getAnnotations().get(0);
Document targetDoc = targetFile.getDocument();
Page targetPage = targetDoc.getPages().get(0);
StaticNote targetAnnotation = (StaticNote) sourceAnnotation.clone(targetDoc);
if (keepAppearanceStream) {
// changing properties of an appearance
// rotating the appearance in the appearance rectangle
targetAnnotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100, 10));
} else {
// removing the appearance to allow lower level properties changes
targetAnnotation.setAppearance(null);
}
// changing text background color
targetAnnotation.setColor(new DeviceRGBColor(0, 0, 1));
if (keepRichText) {
// changing rich text properties
PdfString richText = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.RC);
String richTextString = richText.getStringValue();
// replacing the font family
richTextString = richTextString.replaceAll("font-family:Helvetica", "font-family:Courier");
richText = new PdfString(richTextString);
targetAnnotation.getBaseDataObject().put(PdfName.RC, richText);
} else {
targetAnnotation.getBaseDataObject().remove(PdfName.RC);
targetAnnotation.getBaseDataObject().remove(PdfName.DS);
}
// changing default appearance properties
PdfString defaultAppearance = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.DA);
String defaultAppearanceString = defaultAppearance.getStringValue();
// replacing the font
defaultAppearanceString = defaultAppearanceString.replaceFirst("Helv", "HeBo");
// replacing the text and line color
defaultAppearanceString = defaultAppearanceString.replaceFirst(". . . rg", ".5 g");
defaultAppearance = new PdfString(defaultAppearanceString);
targetAnnotation.getBaseDataObject().put(PdfName.DA, defaultAppearance);
// changing the text value
PdfString contents = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.Contents);
String contentsString = contents.getStringValue();
contentsString = contentsString.replaceFirst("text", "text line");
contents = new PdfString(contentsString);
targetAnnotation.getBaseDataObject().put(PdfName.Contents, contents);
// change the line width and style
targetAnnotation.setBorder(new Border(0, new LineDash(new double[] {3, 2})));
targetPage.getAnnotations().add(targetAnnotation);
targetFile.save(new File(RESULT_FOLDER, "test123-withCalloutCopy.pdf"), SerializationModeEnum.Standard);
}
(CopyCallOut test testCopyCallout)
Beware, the code only has proof-of-concept quality: For arbitrary PDFs you cannot simply expect a string replace of "font-family:Helvetica" by "font-family:Courier" or "Helv" by "HeBo" or ". . . rg" by ".5 g" to do the job: fonts can be given using different style attributes or names, and different coloring instructions may be used.
Screenshots in Adobe
The original file:
keepAppearanceStream = true:
keepAppearanceStream = false and keepRichText = true:
keepAppearanceStream = false and keepRichText = false:
As a post commment Mkl
Your great advice is really helpful for when creating new annotations. I did apply the following as a method of "copying" an existing annotation where note is the "cloned" annotation ad baseAnnotation the source
foreach (PdfName t in baseAnnotation.BaseDataObject.Keys)
{
if (t.Equals(PdfName.DA) || t.Equals(PdfName.DS) || t.Equals(PdfName.RC) || t.Equals(PdfName.Rotate))
{
note.BaseDataObject[t] = baseAnnotation.BaseDataObject[t];
}
}
Thanks again

How to move an image in Lua?

I am new to Lua programming and I am having problems while trying to move an image from a set of coordinates to another.
What I am trying to create is to be used with the X-Plane flight simulator. There is a library called SASL (www.1-sim.com), that was created to make plugins (for X-Plane) creation easir, since the default language is C++ and many people find it difficult.
In general, SASL works as a bridge between Lua and X-Plane, in general lines, the scripts you write reads some data straight from X-Plane (DataRefs) while it is running and depending on the code you wrote its execute commands or many other things that it is possible.
So, when using SASL to create cockpit/panel gauges it uses a base file, named 'avionics.lua' that works as a class and loads all gauges you create for the specific aircraft you are working on. For example my avionics.lua file looks like this:
size = { 2048, 2048 }
components = {
flaps {};
};
where, 'size' is the size that will be used for things to be drawn and components is an array of gauges, in this case the flaps gauge.
The rest of the work is to create the gauge functionality and this is done in a separate file, in my case, called 'flaps.lua'.
Within flaps.lua, is where I need to code the flaps indicator functionality which is to load 2 images: one for the back ground and the second one for the flaps indicator.
The first image is a fixed image. The second one will move throught the 'y' axis based on the flaps indicator DataRef (flapsDegree property below).
The code below when X-Plane is running displays the background image and the flaps indicator on its first stage which is 0 as you can see on the image.
size = {78,100}
local flapsDegree = globalPropertyf("sim/cockpit2/controls/flap_ratio")
local background = loadImage("gfx/Flaps.png")
local indicator = loadImage("gfx/Flaps_Indicator.png")
local flaps = get(flapsPosition)
components = {
texture { position = {945, 1011, 60, 100}, image = background},
texture { position = {959, 1097, 30, 9}, image = indicator},
}
Image
Now, the problem comes when I need to implement the logic for moving the 'indicator' image through the 'y' axis.
I have tried this code without success:
if flaps == 0.333 then
indicator.position = {959, 1075, 30, 9}
end
So how could I accomplish that?
I am not familiar with the SALS library. I just had a quick look into it.
Everything you need to know is in the manuals on the website you linked.
In particular http://www.1-sim.com/files/SASL300.pdf
Everytime your screen is updated each components draw() function will be called.
So if you want to change something dynamically you have to put that into the component's draw function.
If you open the SALS sources you'll find basic components which show you how to use that stuff. One of them is needle.lua:
-- default angle
defineProperty("angle", 0)
-- no image
defineProperty("image")
function draw(self)
local w, h = getTextureSize(get(image))
local max = w
if h > max then
max = h
end
local rw = (w / max) * 100
local rh = (h / max) * 100
drawRotatedTexture(get(image), get(angle),
(100 - rw) / 2, (100 - rh) / 2, rw, rh)
end
If you check the manual you'll find that there is not only a drawRotatedTexture function but many other functions for drawing stuff. Just play around. Try drawTexture for your purpose.
If you don't know what you have to program, open every single lua file in the library and read it together with the Lua reference manual and the SALS documentation until you understand what is going on. Once you understand the existing code you can extend it with ease.

can't set a property for flex container in segment widgets

I am new to Kony framework. Now i am going through Widget. There i came across Segment widgets using I would create a flex container with some labels and textbox.
My UI design are :
1. I Created a segment and set a flex container with some labels and text box in that segment
2. After that I turn off the flex container visible
3. And I type a code like :
function flex()
{
frmAssign.sgmt1.flex1.isVisible = true;//to show flex as visible but it does not read the property of that flex
}
In simple terms just If I click segment first row flex container isVisible should be true
enter image description here
want to achieve this design in kony
Try change frmAssign.sgmt1.flex1.isVisible = true;
frmAssign.sgmt1.flex1.setVisibility(true);
You cannot access the widget of segment directly.
You have to create a property (eg:isVisible) in Master Data of the segment.
initial Value of this property would be "false",
Then change the value as you per your need.
To change properties in segment data you have change the properties in array which you have set to data of segment.
Basically idea is
if you are using masterdata then you need to read the data change
property values and reassign.
if you are dynamically setting data
then you need to change that array and reassign
// always check for Null for selecteindex
//Note keep your existing properties and just change isVisible to true
var selecteindex= frmAssign.sgmt1.selectedRowIndex;
var segData = frmAssign.sgmt1.data[selecteindex];
segData[selecteindex] =("YourFlexName": {
"text": "CButton1",
"isVisible":true
});
form1.segment1.setDataAt(segData,selecteindex);
The right way to do this is :
var selectedIndex= frmAssign.sgmt1.selectedRowIndex;
var rowData = frmAssign.sgmt1.data[selectedIndex];
rowData["flex1"]["isVisible"] = true;
form1.segment1.setDataAt(rowData, selectedIndex);

How to change base layer using JS and leaflet layers control

I have to modify existing application, where leaflet layers control is used - I need to display one of the base layers when the map is initiated. Is there a way, how to call some function from the layers control from JS script - something like control.select(1) ....? If not, how can add a tile layer in the same way as it is done by the control - when I add new L.TileLayer during map init, it's not overwritten by manual layers control selection change?
You could try to emulate a user click on the Leaflet Layers Control, but there is a much more simple way to achieve what you initially describe.
Normally by simply adding a layer to the map (e.g. myTileLayer.addTo(map)), if that layer is part of the base layers or overlays of the Layers Control, the latter will automatically update its status (if you added a base layer, the radio buttons will be selected accordingly; for an overlay, the corresponding checkbox will be ticked).
Now I am not sure I understood properly your last part ("when I add new L.TileLayer during map init, it's not overwritten by manual layers control selection change").
If you mean you have an unexpected behaviour because the Tile Layer you added is not changed by the Layers Control, it may be due to the fact that you are not re-using a Tile Layer that the Layers Control knows: do not use new L.TileLayer, but re-use one of the base layers or overlays.
For example:
var baselayers = {
"Tile Layer 1": L.tileLayer(/* ... */),
"Tile Layer 2": L.tileLayer(/* ... */),
"Tile Layer 3": L.tileLayer(/* ... */)
};
var overlays = {};
L.control.layers(baselayers, overlays).addTo(map);
baseLayers["Tile Layer 1"].addTo(map);
There are several ways to handle this problem.
1) You can select second baselayer by clicking on the radio input in layer control. This can be done programatically like this (not recommended):
var layerControlElement = document.getElementsByClassName('leaflet-control-layers')[0];
layerControlElement.getElementsByTagName('input')[1].click();
2) Just change the order of baseLayers passed into L.Control.Layers during initialization.
3) Extend L.Control.Layers so that it accepts some new option {"selectedBaseLayerIndex": 1}
I found this after digging in the leaflet code:
1) find the layer you want to display in control's structure _layers
2) call map.addLayer(_layers[your_layer_index].layer)
3) find your layer in control's structure _form
4) set it's checked attribute to true
Thank you ghybs. You help me to understand leaflet.
I keep base-map preference in FireBase and get it back on connection to store via Redux.
Now my Map component re-render with tileLayer from Redux.
Before I tried to pass it on props... But with leaflet, like ghybs says, you have to add it again to the map, even if you gave it with something like :
const mapRef = useRef(); //Useful to reach Map leaflet element
layerRef.current = L.control
.layers(baseMaps, null, { position: "topleft", sortLayers: true})
.addTo(map);
And after, I hook my tileLayer :
useEffect(() => {
const { leafletElement: map } = mapRef.current; //Don't forget the current...
baseMaps[tileLayer].addTo(map);
}, [tileLayer]);
return (
<Map
onbaselayerchange={(ev) => handleBaseLayerChange(ev.name)}
layers={defaultLayer(tileLayer)}
ref={mapRef}
{...fieldProps}>
<CustomersMarkers layer={layerRef} customers={customers} />
</Map>
);
If you are using jQuery you can simulate a click on the Layers control to change the base layer:
$('.leaflet-control-layers-selector')[0].click()
If you want to switch to the second map layer use the next index [1]

Resources