ArrayList Processing - How to access each index separately - arraylist

As it is a first time I'm using ArrayList in Processing I'm experiencing some issues.
I have created an Arraylist that stores a PVector (x,y position) of an Ellipsee.
What I'm trying to do is very simple I think but I can't find much info on ArrayLists.
Code:
ArrayList position;
void setup()
{
position= new ArrayList<Vectors>();
}
void draw()
{
position.get(i).display(); //display ellipse
}
void mousePressed()
{
position.add(new Vectors(new PVector(mouseX, mouseY)));
}
So every time mouse is Pressed a new ellipse is created at mouseX mouseY position. What I would like to do is when my I created an amount ellipses, I need to control each one separately to change it's size or color either by clicking on them or with KeyPressed().

This won't compile automatically as I'm assuming your PVector object has already been created and that it has two public attributes of xPosition and yPosition:
// Initialise your arraylist
ArrayList<PVector> listOfPVectors = new ArrayList<PVector>;
// Objects can be added to your list as follows:
PVector pvectorObject = new PVector();
listOfPVectors.add(pvectorObject);
// The size of your ArrayList can be output as follows:
println(listOfPVectors.size());
// You can iterate through every entry in the arraylist as follows:
for(int index = 0; index < listOfPVectors.size(); index ++) {
println("X Position Value = " + listOfPVectors.get(index).xPosition);
println("Y Position Value = " + listOfPVectors.get(index).yPosition);
}
Basically, you use the ArrayList.get(indexPosition) method to retrieve any element you want from your ArrayList. You can then work away with it as normal.
Hope this helps!

Related

UWP - Saving Settings does not work all the time

I've got the following code just copied from here. I want to bind a double value to a xaml slider, get this value from the localsetting every time I navigate to the SettingsPage and everytime the slidervalue gets changed by the user I want it to be saved to localsettings. Here is my code so far:
SettingsPage.xaml.cpp:
Windows::Storage::ApplicationDataContainer^ localSettings = Windows::Storage::ApplicationData::Current->LocalSettings;
SettingsPage::SettingsPage()
{
InitializeComponent();
this->viewModel = ref new SettingsViewModel();
this->DataContext = this->viewModel;
}
void SettingsPage::QSlider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
{
Windows::Storage::ApplicationDataCompositeValue^ composite =ref new Windows::Storage::ApplicationDataCompositeValue();
bool a = composite->Insert(SETTINGS_TAG_SLIDER_Q, dynamic_cast<PropertyValue^>(PropertyValue::CreateDouble((double)sldQ->Value)));
auto values = localSettings->Values;
bool b = values->Insert(SETTINGS_TAG_SETTINGS_PAGE, composite);
}
SettingsPage.xaml:
<Slider x:Name="sldQ" Margin="15,5,15,0" Value="{Binding SliderQValue}" ValueChanged="Slider_ValueChanged" MaxWidth="300" HorizontalContentAlignment="Left" ></Slider>
SettingsViewModel.cpp:
double SettingsViewModel::SliderQValue::get()
{
Windows::Storage::ApplicationDataContainer^ localSettings = Windows::Storage::ApplicationData::Current->LocalSettings;
ApplicationDataCompositeValue^ composite = safe_cast<ApplicationDataCompositeValue^>(localSettings->Values->Lookup(SETTINGS_TAG_SETTINGS_PAGE));
if (composite != nullptr)
{
if (composite->HasKey(SETTINGS_TAG_SLIDER_Q)) {
double value = safe_cast<IPropertyValue^>(composite->Lookup(SETTINGS_TAG_SLIDER_Q))->GetDouble();
return value;
}
}
return 99;
}
My Problem is that this works exactly once! If I navigate from other pages to SettingsPage, I get slidervalue=99. Then I set it by dragging to e.g. 50. Then I navigat back to other page. From the other page I navigate again to SettingsPage and get slidervalue=50. But doing it once again I get 99 again. So it only works for 1 page navigation-cycle but it should work even if the app is rebooted. What is the problem in my code? Am I understanding something wrong?
I actually solved the problem with the help of this. In my code above I was initializing a new 'ApplicationDateCompositeValue' each time I wanted to write/read it. So with the new method it works like it was planned to do:
OnValueChanged:
Windows::Storage::ApplicationDataContainer^ localSettings = Windows::Storage::ApplicationData::Current->LocalSettings;
auto values = localSettings->Values;
values->Insert(TAG_SLIDER, dynamic_cast<PropertyValue^>(PropertyValue::CreateDouble((double)sldQuality->Value)));
Property::get():
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
auto values = localSettings->Values;
if (localSettings->Values->HasKey(TAG_SLIDER)) {
double value = safe_cast<double>(localSettings->Values->Lookup(TAG_SLIDER));
return value;
}
else
return default_value;

How to fetch all the fields from ServiceFeatureTable in arcgis

I am using arcgis library 100.0.0 in android for displaying maps and information inside map.
I am using the following code to populate a ServiceFeaturetable using URL provided by arcGis. I am able to load the feature layer successfully into the mapview. I have written code that listens to the click on the symbol on the map, so that I can get some information about the specific feature on the map. I am able to get the specific feature OnClick.
Upon investigating the GetAttributes() result of the specific feature, I realize that it is not having all the fields. After investigating on internet, I found that the FeatureTable.QueryFeaturesAsync could be used to get all the fields of the feature. Even though I have written the code to get all the fields, I do not know how I link this result with the feature layer, so that the feature has all the fields that I require. Here is the code
final ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable("some URL");
ListenableFuture<FeatureQueryResult> queryresult = serviceFeatureTable.queryFeaturesAsync(null, ServiceFeatureTable.QueryFeatureFields.LOAD_ALL);
// create the feature layer using the service feature table
final FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
featureLayer.setSelectionColor(Color.YELLOW);
featureLayer.setSelectionWidth(10);
// add the layer to the map
mapView.getMap().getOperationalLayers().add(featureLayer);
// set an on touch listener to listen for click events
mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(getContext(), mapView) {
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// get the point that was clicked and convert it to a point in map coordinates
Point clickPoint = mMapView.screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())));
int tolerance = 10;
double mapTolerance = tolerance * mMapView.getUnitsPerDensityIndependentPixel();
// create objects required to do a selection with a query
Envelope envelope = new Envelope(clickPoint.getX() - mapTolerance, clickPoint.getY() - mapTolerance, clickPoint.getX() + mapTolerance, clickPoint.getY() + mapTolerance, mapView.getMap().getSpatialReference());
QueryParameters query = new QueryParameters();
query.setGeometry(envelope);
// call select features
final ListenableFuture<FeatureQueryResult> future = featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
// add done loading listener to fire when the selection returns
future.addDoneListener(new Runnable() {
#Override
public void run() {
try {
//call get on the future to get the result
FeatureQueryResult result = future.get();
// create an Iterator
Iterator<Feature> iterator = result.iterator();
Feature feature;
// cycle through selections
int counter = 0;
while (iterator.hasNext()){
feature = iterator.next();
counter++;
String name = feature.getAttributes().get(Constants.FIELD_NAME).toString();
Log.d(getResources().getString(R.string.app_name), "Selection #: " + counter + " Table name: " + feature.getFeatureTable().getTableName());
}
//Toast.makeText(getApplicationContext(), counter + " features selected", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(getResources().getString(R.string.app_name), "Select feature failed: " + e.getMessage());
}
}
});
return super.onSingleTapConfirmed(e);
}
});
Try replacing your code
from
final ListenableFuture<FeatureQueryResult> future = featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
to
final ListenableFuture<FeatureQueryResult> future = serviceFeatureTable.queryFeaturesAsync(query, ServiceFeatureTable.QueryFeatureFields.LOAD_ALL);
It works for me!

iText LocationTextExtractionStrategy/HorizontalTextExtractionStrategy splits text into single characters

I used a extended version of LocationTextExtractionStrategy to extract connected texts of a pdf and their positions/sizes. I did this by using the locationalResult. This worked well until I tested a pdf containing texts with a different font (ttf). Suddenly these texts are splitted into single characters or small fragments.
For example "Detail" is not any more one object within the locationalResult list but splitted into six items (D, e, t, a, i, l)
I tried using the HorizontalTextExtractionStrategy by making the getLocationalResult method public:
public List<TextChunk> GetLocationalResult()
{
return (List<TextChunk>)locationalResultField.GetValue(this);
}
and using the PdfReaderContentParser to extract the texts:
reader = new PdfReader("some_pdf");
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
var strategy = parser.ProcessContent(i, HorizontalTextExtractionStrategy());
foreach (HorizontalTextExtractionStrategy.HorizontalTextChunk chunk in strategy.GetLocationalResult())
{
// Do something with the chunk
}
but this also returns the same result.
Is there any other way to extract connected texts from a pdf?
I used a extended version of LocationTextExtractionStrategy to extract connected texts of a pdf and their positions/sizes. I did this by using the locationalResult. This worked well until I tested a pdf containing texts with a different font (ttf). Suddenly these texts are splitted into single characters or small fragments.
This problem is due to wrong expectations concerning the contents of the LocationTextExtractionStrategy.locationalResult private list member variable.
This list of TextChunk instances contains the pieces of text as they were forwarded to the strategy from the parsing framework (or probably as they were preprocessed by some filter class), and the framework forwards each single string it encounters in a content stream separately.
Thus, if a seemingly connected word in the content stream actually is drawn using multiple strings, you get multiple TextChunk instances for it.
There actually is some "intelligence" in the method getResultantText joining these chunks properly, adding a space where necessary and so on.
In case of your document, "DETAIL " usually is drawn like this:
[<0027> -0.2<00280037> 0.2<0024002c> 0.2<002f> -0.2<0003>] TJ
As you see there are slight text insertion point moves between 'D' and 'E', 'T' and 'A', 'I' and 'L', and 'L' and ' '. (Such mini moves usually represent kerning.) Thus, you'll get individual TextChunk instances for 'D', 'ET', 'AI', and 'L '.
Admittedly, the LocationTextExtractionStrategy.locationalResult member is not very well documented; but as it is a private member, this IMHO is forgivable.
That this worked well for many documents is due to many PDF creators not applying kerning and simply drawing connected text using single string objects.
The HorizontalTextExtractionStrategy is derived from the LocationTextExtractionStrategy and mainly differs from it in the way it arranges the TextChunk instances to a single string. Thus, you'll see the same fragmentation here.
Is there any other way to extract connected texts from a pdf?
If you want "connected texts" as in "atomic string objects in the content stream", you already have them.
If you want "connected texts" as in "visually connected texts, no matter where the constituent letters are drawn in the content stream", you have to glue those TextChunk instances together like the LocationTextExtractionStrategy and HorizontalTextExtractionStrategy do in getResultantText in combination with the comparison methods in their respective TextChunkLocationDefaultImp and HorizontalTextChunkLocation implementations.
After debugging deep into the iTextSharp library I figured out that my texts are drawn with the TJ operator as mkl also mentioned.
[<0027> -0.2<00280037> 0.2<0024002c> 0.2<002f> -0.2<0003>] TJ
iText processes these texts not as a single PdfString but as an array of PdfObjects which ends up in calling renderListener.RenderText(renderInfo) for each PdfString item in it (see ShowTextArray class and DisplayPdfString method). In the RenderText method however the information about the relation of the pdf strings within the array got lost and every item is added to locationalResult as an independent object.
As my goal is to extract the "argument of a single text drawing instruction" I extended the PdfContentStreamProcessor class about a new method ProcessTexts which returns a list of these atomic strings. My workaround is not very pretty as I had to copy paste some private fields and methods from the original source but it works for me.
class PdfContentStreamProcessorEx : PdfContentStreamProcessor
{
private IDictionary<int, CMapAwareDocumentFont> cachedFonts = new Dictionary<int, CMapAwareDocumentFont>();
private ResourceDictionary resources = new ResourceDictionary();
private CMapAwareDocumentFont font = null;
public PdfContentStreamProcessorEx(IRenderListener renderListener) : base(renderListener)
{
}
public List<string> ProcessTexts(byte[] contentBytes, PdfDictionary resources)
{
this.resources.Push(resources);
var texts = new List<string>();
PRTokeniser tokeniser = new PRTokeniser(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource(contentBytes)));
PdfContentParser ps = new PdfContentParser(tokeniser);
List<PdfObject> operands = new List<PdfObject>();
while (ps.Parse(operands).Count > 0)
{
PdfLiteral oper = (PdfLiteral)operands[operands.Count - 1];
if ("Tj".Equals(oper.ToString()))
{
texts.Add(getText((PdfString)operands[0]));
}
else if ("TJ".Equals(oper.ToString()))
{
string text = string.Empty;
foreach (PdfObject entryObj in (PdfArray)operands[0])
{
if (entryObj is PdfString)
{
text += getText((PdfString)entryObj);
}
}
texts.Add(text);
}
else if ("Tf".Equals(oper.ToString()))
{
PdfName fontResourceName = (PdfName)operands[0];
float size = ((PdfNumber)operands[1]).FloatValue;
PdfDictionary fontsDictionary = resources.GetAsDict(PdfName.FONT);
CMapAwareDocumentFont _font;
PdfObject fontObject = fontsDictionary.Get(fontResourceName);
if (fontObject is PdfDictionary)
_font = GetFont((PdfDictionary)fontObject);
else
_font = GetFont((PRIndirectReference)fontObject);
font = _font;
}
}
this.resources.Pop();
return texts;
}
string getText(PdfString #in)
{
byte[] bytes = #in.GetBytes();
return font.Decode(bytes, 0, bytes.Length);
}
private CMapAwareDocumentFont GetFont(PRIndirectReference ind)
{
CMapAwareDocumentFont font;
cachedFonts.TryGetValue(ind.Number, out font);
if (font == null)
{
font = new CMapAwareDocumentFont(ind);
cachedFonts[ind.Number] = font;
}
return font;
}
private CMapAwareDocumentFont GetFont(PdfDictionary fontResource)
{
return new CMapAwareDocumentFont(fontResource);
}
private class ResourceDictionary : PdfDictionary
{
private IList<PdfDictionary> resourcesStack = new List<PdfDictionary>();
virtual public void Push(PdfDictionary resources)
{
resourcesStack.Add(resources);
}
virtual public void Pop()
{
resourcesStack.RemoveAt(resourcesStack.Count - 1);
}
public override PdfObject GetDirectObject(PdfName key)
{
for (int i = resourcesStack.Count - 1; i >= 0; i--)
{
PdfDictionary subResource = resourcesStack[i];
if (subResource != null)
{
PdfObject obj = subResource.GetDirectObject(key);
if (obj != null) return obj;
}
}
return base.GetDirectObject(key); // shouldn't be necessary, but just in case we've done something crazy
}
}
}

How do I control the frequency of labels on LineDataSet?

In MPAndroidChart, I can control the frequency of xaxis values with setSkipLabels. However, this only affects the xaxis. How do I do the same with the lines themselves in a line chart?
I don't think the library provide a neat way to do this for LineDataSet as for X axis.
The best bet IMHO should be to use a custom ValueFormatter to set text to blank as required.
Exemple to show one label out of ten:
public class MyValueFormatter implements ValueFormatter {
private DecimalFormat mFormat;
public MyValueFormatter() {
mFormat = new DecimalFormat("###,###,##0.0"); // use one decimal
}
#Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
String output = "";
if (entry.getXIndex() % 10 == 0) output = mFormat.format(value);
return output;
}
}
Then, attach your formatter to your DataSet
lineDataSet.setValueFormatter(new MyValueFormatter());
This will only affect text displayed next to each value in the graph.
You could also disable drawing the circle on each value with :
lineDataSet.setDrawCircles(false);

Unable to get page number when using RenderListener interface to find a piece of text in PDF

iText requires coordinates to create form fields and Page Number in existing PDFs at different places.
My PDF is dynamic. So I decided to creat the PDF with some identifier text. And use TextRenderInfo to find the coordinates for the text and use those coordinates to creat the textfields and other form fields.
ParsingHelloWorld.java
public void extractText(String src, String dest) throws IOException, DocumentException {
PrintWriter out = new PrintWriter(new FileOutputStream(dest));
PdfReader reader = new PdfReader(src);
PdfStamper stp = new PdfStamper(reader, new FileOutputStream(dest);
RenderListener listener = new MyTextRenderListener(out,reader,stp);
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
for ( int pageNum= 0; pageNum < reader.getNumberOfPages(); pageNum++ ){
PdfDictionary pageDic = reader.getPageN(pageNum);
PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);
}
out.flush();
out.close();
stp.close();
}
MyTextRenderListener.java
public void renderText(TextRenderInfo renderInfo) {
if (renderInfo.getText().startsWith("Fill_in_TextField")){
// creates the text fields by getting co-ordinates form the renderinfo object.
createTextField(renderInfo);
}else if (renderInfo.getText().startsWith("Fill_in_SignatureField")){
// creates the text fields by getting co-ordinates form the renderinfo object.
createSignatureField(renderInfo);
}
}
The problem is I have a page number in extractText method in the ParsingHelloWorld class.
When the renderText method is called inside the MyTextRenderListener class internally processing the page content, I couldn't get the pageNumber to generate the fields in the PDF at the particular coordinates where the identifier text resides(ex Fill_in_TextField,Fill_in_SignatureField..etc ).
Any suggestions/ ideas to get the page number in my scenario.
Thanks in advance.
That's easy. Add a parameter to MyTextListener:
protected int page;
public void setPage(int page) {
this.page = page;
}
Now when you loop over the pages in ParsingHelloWorld, pass the page number to MyTextListener:
listener.setPage(pageNum);
Now you have access to that number in the renderText() method and you can pass it to your createTextField() method.
Note that I think your loop is wrong. Page numbers don't start at page 0, they start at page 1.