I have a class which I used to overlay rectangles on maps. But I am not able to figure out how to remove the previous overlay's to draw new rectangles if a new set of results are provided to my displayOnMap method.
To provide more insight on the draw method. It takes in PlotSetOutput as an argument which contains centers and each center contains a set of lat/long co-ordinates. Hence the logic for looping over it and creating lat/long bounds and assigning it to rectangle objects.
public class displayOnMap extends Composite {
private final VerticalPanel pWidget;
private MapWidget mapWidget;
private static Rectangle rectangle;
private RectangleOptions rectOpts;
private static final LatLng USCENTER = LatLng.newInstance(33.68,-116.17);
public displayOnMap(PlotSetOutput result) {
pWidget = new VerticalPanel();
initWidget(pWidget);
draw(result);
}
private void draw(PlotSetOutput result) {
MapOptions mapOpts = MapOptions.newInstance();
mapOpts.setZoom(4);
mapOpts.setCenter(USCENTER);
mapOpts.setMapTypeId(MapTypeId.TERRAIN);
mapWidget = new MapWidget(mapOpts);
pWidget.add(mapWidget);
mapWidget.setSize("800px", "800px");
ArrayList<Centers> listOfCenters = new ArrayList<Centers>();
List<ResultClusterPlots> finalCluster = result.getFinalcluster();
int totalNumberOfClusters = result.getTotalNumberOfClusters();
for (int i = 0; i < totalNumberOfClusters; i++) {
listOfCenters.add(i, new Centers());
}
for (int j = 0; j < finalCluster.size(); j++) {
Centers p = listOfCenters.get(finalCluster.get(j).getClusterID()-1);
LatLng ne = LatLng.newInstance(finalCluster.get(j).getLatitude()
.get(0), finalCluster.get(j).getLongitude().get(0));
LatLng sw = LatLng.newInstance(finalCluster.get(j).getLatitude()
.get(1), finalCluster.get(j).getLongitude().get(1));
p.setLatLongArr(LatLngBounds.newInstance(ne,sw));
}
for (int k = 0; k < listOfCenters.size(); k++) {
ArrayList<LatLngBounds> ltlgBound = listOfCenters.get(k).getLatLongArr();
String color = getRandomColor();
for (int l = 0; l < ltlgBound.size(); l++) {
rectOpts = RectangleOptions.newInstance();
rectOpts.setStrokeColor("#FF0000");
rectOpts.setStrokeOpacity(0.3);
rectOpts.setStrokeWeight(2);
rectOpts.setFillColor(color);
rectOpts.setFillOpacity(0.35);
rectOpts.setMap(mapWidget);
rectOpts.setBounds(ltlgBound.get(l));
rectangle = Rectangle.newInstance(rectOpts);
rectangle.setMap(mapWidget);
}
}
}
}
Output when the method (displayOnMap) is invoked for the first time. Everything works fine.
Output when the displayOnMap method is called with a second query.
I tried to do rectangle.setMap(null); pWidget.removeFromParent(); but I kept getting the same result.
I have had the same problem, the only way I could hide / delete / show the overlays was through the OverlayCompleteMapEvent.
As I understand it isn't possible to get a hook to an overlay before it is completed, once it is completed the only way to get a hook on it is handling "OverlayCompleteMapEvent" event. I used a list to store the Overlays and then I could hide/show/delete them.
Related
I am sure that everybody knows about this script, http://wiki.unity3d.com/index.php/Floating_Origin, that fixes problems with floating origin easily.
The problem is that the script is outdated and does not move the particle effects created by visual effect graph.
I was trying to rewrite it but I cant seem to make an array to store all the particles, like with the previous one, thus I can't continue from there.
Here is my code:
// Based on the Unity Wiki FloatingOrigin script by Peter Stirling
// URL: http://wiki.unity3d.com/index.php/Floating_Origin
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.VFX;
using UnityEngine.Experimental.VFX;
public class FloatingOrigin : MonoBehaviour
{
[Tooltip("Point of reference from which to check the distance to origin.")]
public Transform ReferenceObject = null;
[Tooltip("Distance from the origin the reference object must be in order to trigger an origin shift.")]
public float Threshold = 5000f;
[Header("Options")]
[Tooltip("When true, origin shifts are considered only from the horizontal distance to orign.")]
public bool Use2DDistance = false;
[Tooltip("When true, updates ALL open scenes. When false, updates only the active scene.")]
public bool UpdateAllScenes = true;
[Tooltip("Should ParticleSystems be moved with an origin shift.")]
public bool UpdateParticles = true;
[Tooltip("Should TrailRenderers be moved with an origin shift.")]
public bool UpdateTrailRenderers = true;
[Tooltip("Should LineRenderers be moved with an origin shift.")]
public bool UpdateLineRenderers = true;
private ParticleSystem.Particle[] parts = null;
VisualEffect[] visualEffect = null;
void LateUpdate()
{
if (ReferenceObject == null)
return;
Vector3 referencePosition = ReferenceObject.position;
if (Use2DDistance)
referencePosition.y = 0f;
if (referencePosition.magnitude > Threshold)
{
MoveRootTransforms(referencePosition);
if (UpdateParticles)
MoveParticles(referencePosition);
if (UpdateTrailRenderers)
MoveTrailRenderers(referencePosition);
if (UpdateLineRenderers)
MoveLineRenderers(referencePosition);
}
}
private void MoveRootTransforms(Vector3 offset)
{
if (UpdateAllScenes)
{
for (int z = 0; z < SceneManager.sceneCount; z++)
{
foreach (GameObject g in SceneManager.GetSceneAt(z).GetRootGameObjects())
g.transform.position -= offset;
}
}
else
{
foreach (GameObject g in SceneManager.GetActiveScene().GetRootGameObjects())
g.transform.position -= offset;
}
}
private void MoveTrailRenderers(Vector3 offset)
{
var trails = FindObjectsOfType<TrailRenderer>() as TrailRenderer[];
foreach (var trail in trails)
{
Vector3[] positions = new Vector3[trail.positionCount];
int positionCount = trail.GetPositions(positions);
for (int i = 0; i < positionCount; ++i)
positions[i] -= offset;
trail.SetPositions(positions);
}
}
private void MoveLineRenderers(Vector3 offset)
{
var lines = FindObjectsOfType<LineRenderer>() as LineRenderer[];
foreach (var line in lines)
{
Vector3[] positions = new Vector3[line.positionCount];
int positionCount = line.GetPositions(positions);
for (int i = 0; i < positionCount; ++i)
positions[i] -= offset;
line.SetPositions(positions);
}
}
private void MoveParticles(Vector3 offset)
{
var particles = FindObjectsOfType<ParticleSystem>() as ParticleSystem[];
foreach (ParticleSystem system in particles)
{
if (system.main.simulationSpace != ParticleSystemSimulationSpace.World)
continue;
int particlesNeeded = system.main.maxParticles;
if (particlesNeeded <= 0)
continue;
bool wasPaused = system.isPaused;
bool wasPlaying = system.isPlaying;
if (!wasPaused)
system.Pause();
// ensure a sufficiently large array in which to store the particles
if (parts == null || parts.Length < particlesNeeded)
{
parts = new ParticleSystem.Particle[particlesNeeded];
}
// now get the particles
int num = system.GetParticles(parts);
for (int i = 0; i < num; i++)
{
parts[i].position -= offset;
}
system.SetParticles(parts, num);
if (wasPlaying)
system.Play();
}
var particles2 = FindObjectsOfType<VisualEffect>() as VisualEffect[];
foreach (VisualEffect system in particles2)
{
int particlesNeeded = system.aliveParticleCount;
if (particlesNeeded <= 0)
continue;
bool wasPaused = !system.isActiveAndEnabled;
bool wasPlaying = system.isActiveAndEnabled;
if (!wasPaused)
system.Stop();
// ensure a sufficiently large array in which to store the particles
if (visualEffect == null || visualEffect.Length < particlesNeeded)
{
visualEffect = new VisualEffect().visualEffectAsset[particlesNeeded];
}
// now get the particles
int num = system.GetParticles(parts);
for (int i = 0; i < num; i++)
{
parts[i].position -= offset;
}
system.SetParticles(parts, num);
if (wasPlaying)
system.Play();
}
}
}
On the line(this is a wrong line and everything below it too)
visualEffect = new VisualEffect().visualEffectAsset[particlesNeeded];
, I need to create a similar array to the line (correct one, but for the old particle system)
parts = new ParticleSystem.Particle[particlesNeeded];
that creates array full of particles (but with VisualEffect class).
If I can fix this one, there should not be any problem with the rest.
I think that solving this problem will help literally thousands of people now and in the future, since limitation for floating origin in unity are horrible and majority of people working in unity will need floating origin for their game worlds, with VFX graph particles.
Thanks for the help.
My question has been answered here:
https://forum.unity.com/threads/floating-origin-and-visual-effect-graph.962646/#post-6270837
We're using Verlet method to move a Tukey. But it only moves it once and not continuously. The codes for updating the position of the Turkey is in Update() method so it should rune every frame. But It only runed once.
Futhermore, we put three times the codes for updating the position of the Turkey Line rendered object in the update method and it seems that the new position of the Turkey only move as if we moved it once.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenerateTurkeys : MonoBehaviour
{
public LineRenderer lineRenderer;
// Start is called before the first frame update
//int numberOfTurkeys;
static int NUM_PARTICLES = 26;
float fTimeStep;
Vector3[] m_position = new Vector3[NUM_PARTICLES];
Vector3[] m_acceleration = new Vector3[NUM_PARTICLES];
Vector3[] m_oldPosition = new Vector3[NUM_PARTICLES];
Vector3[] m_newPosition = new Vector3[NUM_PARTICLES];
void Start()
{
lineRenderer = gameObject.GetComponent<LineRenderer>();
lineRenderer.GetPositions(m_position);
for(int i = 0; i < m_acceleration.Length; i++)
{
m_acceleration[i] = new Vector3(0.0f, -9.8f, 0.0f);
}
fTimeStep = 5.5f;
}
// Verlet integration step void ParticleSystem::
void Verlet()
{
var random_direction = Random.Range(-1, 1);
for (int i = 0; i < NUM_PARTICLES; i++)
{
m_newPosition[i] = 2 * m_position[i] - m_oldPosition[i] + m_acceleration[i] * fTimeStep * fTimeStep;
m_oldPosition[i] = m_position[i];
}
}
// Update is called once per frame
void FixedUpdate()
{
Verlet();
lineRenderer.SetPositions(m_newPosition);
}
}
First of all, FixedUpdate is used by the physics engine and updates differently from the normal Update method. Unless what you want to do has to be synced with the physics engine then you should use Update.
Secondly, your m_position vector is never updated, you call lineRenderer.getPositions only in the Start method. Because of this, your m_oldPositions will always be the same and the position won't change. To correct this your Verlet method should also update the m_position vector after the new position has been computed.
Something like this:
void Verlet()
{
var random_direction = Random.Range(-1, 1);
for (int i = 0; i < NUM_PARTICLES; i++)
{
m_newPosition[i] = 2 * m_position[i] - m_oldPosition[i] + m_acceleration[i] * fTimeStep * fTimeStep;
m_oldPosition[i] = m_position[i];
m_position[i] = m_newPosition[i];
}
}
I have a Polygon persisted on a SQL Server 2012 database as Sys.Geography type. How can I obtain all points for the Polygon?
I'm thinking to use AsText() method and parse the string, but maybe there is a better choice?
Found a way, here is an extension method:
public static IEnumerable<MyEntityWithLatAndLng> GetPointsFromPolygon(this System.Data.Entity.Spatial.DbGeography geo)
{
for (int i = 1; i < geo.PointCount; i++)
{
var p = geo.PointAt(i);
yield return new MyEntityWithLatAndLng(){ Latitude = p.Latitude.Value, Longitude = p.Longitude.Value };
}
}
I think Alexandre nearly has this correct, he is missing the last element of the polygon from the points list. See the updated code below.
public static IEnumerable<MyEntityWithLatAndLng> GetPointsFromPolygon(this System.Data.Entity.Spatial.DbGeography geo)
{
for (int i = 1; i <= geo.PointCount; i++)
{
var p = geo.PointAt(i);
yield return new MyEntityWithLatAndLng(){ Latitude = p.Latitude.Value, Longitude = p.Longitude.Value };
}
}
SqlGeography
class has a method STPolyFromText
which allows you to get polygon with array of points.
In C# for example:
SqlGeography poly = SqlGeography.STPolyFromText(
new SqlChars(yourEntity.geoColumn.WellKnownValue.WellKnownText),
yourEntity.geoColumn.CoordinateSystemId);
for (int i = 1; i <= poly.STNumPoints(); i++)
{
SqlGeography point = poly.STPointN(i);
//do something with point
}
I have the following list appearing on UI of an android application which tells about the date and the temperature on that date.
temp degree
11/01 --.-- c
11/02 21.7 c
11/03 22.5 c
Here I want to find the position of string "--.--" and then click on it, so that I can update the list. Is there any way to find the position of string? I know that solo.searchText() will tell whether the string is present or not, but what about the position?
// i think it will help you
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
// TODO Auto-generated method stub
if(yourliststring.trim().equals("--.--"))
{
//your condition
}
else
{
//your condition
}
}
});
I got a simple way to find and click on the string
if(solo.searchText("--.--")){
solo.clickLongOnText("--.--");
}
All I need is to click on the string "--.--".
I'm not sure what position you need, however if you need position on screen you can simple do:
TextView textView = solo.getText("--.--"); // or solo.getText(Pattern.quote("--.--")); if needed
int[] xy = new int[2];
textView.getLocationOnScreen(xy);
final int viewWidth = textView.getWidth();
final int viewHeight = textView.getHeight();
final float x = xy[0] + (viewWidth / 2.0f);
final float y = xy[1] + (viewHeight / 2.0f);
this way you have central point of view (x, y).
If you need position of text in list, you can do:
private int getPosition(ListView listView, String text) {
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
Object o = listView.getAdapter.getItemAtPosition(i);
if (o instanceof TextView) {
if (((TextView)o).getText().toString().equals(text)) {
return i;
}
}
}
return -1; // not found
}
you can call it for instance this way (set proper parameters):
int position = getPosition((ListView) solo.getView(ListView.class, 0), "--.--");
Everything written without testing and even compiling, however main idea should be fine.
I started programming with Processing today and wrote a little programm that creates 10 random rectangles
Now I like to make them disappear when the mouse is over them, but my actual code is not working
I would apprechiate some tipps ...
import java.awt.Rectangle;
Rectangle rect[] = new Rectangle[10];
int xpos[] = new int[10];
int ypos[] = new int[10];
int size = 25;
boolean visible[] = new boolean[10];
void setup()
{
size(640,480);
frameRate(60);
smooth();
background(0);
stroke(255);
fill(255);
textAlign(CENTER);
textSize(200);
text("Catch", width/2, 280);
textSize(100);
text("them", width/2, 380);
// 10 Random positions for the rectangles
for (int i=0; i < 10; i++) {
xpos[i] = int(random (615));
ypos[i] = int(random (455));
visible[i] = true;
}
for (int i=0; i < 10; i++) {
rect[i] = new Rectangle(xpos[i],ypos[i],size,size);
}
}
void draw()
{
for (int i=0; i < 10; i++) {
if (visible[i] == true){
fill(255,0,0);
rect(rect[i].x,rect[i].y,rect[i].width,rect[i].height);}
else if (rect[i].contains(mouseX,mouseY)){
visible[i] = false; }
}}
Why else if? The way it is written, it will only check to see if the mouse is over a rect if visible[i] == false. They are all visible so it never gets executed.
Also to see the effect, you must call background(0); at the top of your draw method. Otherwise you never clear the screen to see the results.
You should also consider cleaning up your indentation and braces {} to make sure you are formatting the code in a consistent way. That would make it easier to read.