How to return Lat/Long with MouseMove in GMap.net - onmousemove

I am trying to put together a c# program with GMap, and I'd like the coordinates where the mouse is to show up on the bottom of the screen. I've added an OnMouseMove method to the form, and I do get coordinates out, but only if the mouse is not over the map itself. If the mouse is over the map it does not respond. I am fairly new to c#, so I am probably missing something fairly simple. Any ideas? Below is the code I'm using right now.
public partial class Form1 : Form
{
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
{
base.OnMouseMove(e);
if(e.Button == MouseButtons.Left)
{
int itest=2;
}
double X = mapexplr.FromLocalToLatLng(e.X, e.Y).Lng;
double Y = mapexplr.FromLocalToLatLng(e.X, e.Y).Lat;
string longitude = X.ToString();
string latitude = Y.ToString();
LongStrip.Text = longitude;
LatStrip.Text = latitude;
}
GMapOverlay overlayOne;
public Form1()
{
InitializeComponent();
}
private void mapexplr_Load(object sender, EventArgs e)
{
//initialisation de notre map
mapexplr.MapProvider = GMap.NET.MapProviders.BingMapProvider.Instance;
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
mapexplr.Position = new PointLatLng(35.571458, -85.547961);
mapexplr.DragButton = MouseButtons.Left;
mapexplr.SetCurrentPositionByKeywords("Tunisia");
mapexplr.MapProvider = GMapProviders.BingMap;
mapexplr.MinZoom = 3;
mapexplr.MaxZoom = 17;
mapexplr.Zoom = 5;
mapexplr.Manager.Mode = AccessMode.ServerAndCache;
//ajout des overlay
overlayOne = new GMapOverlay(mapexplr, "OverlayOne");
//ajout de Markers
overlayOne.Markers.Add(new GMap.NET.WindowsForms.Markers.GMapMarkerGoogleGreen(new PointLatLng(36.657403, 10.327148)));
//ajout de overlay à la map
mapexplr.Overlays.Add(overlayOne);
}
}

private void gMapControl1_MouseMove(object sender, MouseEventArgs e)
{
lat = gMapControl1.FromLocalToLatLng(e.X, e.Y).Lat;
lng = gMapControl1.FromLocalToLatLng(e.X, e.Y).Lng;
label1.Text = "lat= " + Convert.ToString(lat)+ " lng= " +Convert.ToString(lng);
label1.BackColor = Color.Transparent;
mouseY = e.Location.Y;
mouseX = e.Location.X;
label1.Location = new Point(mouseX, mouseY+10);
}

The mouse move event that you used is for the Form not the Gmap. Just take your code and paste is into the Gmap.Net mouse move event. Also you shouldnt initialize your Gmap in a load event and it looks like you were setting the map type twice and your map location twice (once in tunisia and once at 35.571458, -85.547961). Refer below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsForms;
using GMap.NET.WindowsForms.Markers;
namespace Code_Test
{
public partial class Form1 : Form
{
GMapOverlay overlayOne = new GMapOverlay();
public Form1()
{
InitializeComponent();
mapexplr.MapProvider = GMap.NET.MapProviders.BingMapProvider.Instance;
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
mapexplr.Position = new PointLatLng(35.571458, -85.547961);
mapexplr.DragButton = MouseButtons.Left;
mapexplr.MinZoom = 3;
mapexplr.MaxZoom = 17;
mapexplr.Zoom = 5;
}
private void Form1_Load(object sender, EventArgs e)
{
GMarkerGoogle marker = new GMarkerGoogle(new PointLatLng(36.657403, 10.327148), GMarkerGoogleType.green);
overlayOne.Markers.Add(marker);
mapexplr.Overlays.Add(overlayOne);
}
private void mapexplr_MouseMove(object sender, MouseEventArgs e)
{
base.OnMouseMove(e);
double X = mapexplr.FromLocalToLatLng(e.X, e.Y).Lng;
double Y = mapexplr.FromLocalToLatLng(e.X, e.Y).Lat;
string longitude = X.ToString();
string latitude = Y.ToString();
LongStrip.Text = longitude;
LatStrip.Text = latitude;
}
}
}
This code is tested so if you have any problems let me know. Remember to make a reference to GMap.NET.Core and GMap.NET.WindowsForms if you havent already.

Related

Get current Android activity in MAUI android (net6-android) library

I have a library for Xamarin.Forms (Android) allowing to use NFC, with this code :
public class MediaAccessReader : Java.Lang.Object, NfcAdapter.IReaderCallback
{
public const string TypeName = "Nfc";
private static NfcAdapter NfcAdapter { get; } = NfcAdapter.GetDefaultAdapter(Android.App.Application.Context);
public string Name { get; set; }
public void Initialize(MediaAddedEventHandler mediaAdded, MediaRemovedEventHandler mediaRemoved)
{
Name = "Nfc";
#if XAMARINANDROID
var activity = Forms.Context as Activity;
NfcAdapter?.EnableReaderMode(activity, this, NfcReaderFlags.NfcA | NfcReaderFlags.NfcB | NfcReaderFlags.NfcF | NfcReaderFlags.NfcV | NfcReaderFlags.SkipNdefCheck, Bundle.Empty);
#else
var activity = ?????????????????;
NfcAdapter?.EnableReaderMode(activity , this, NfcReaderFlags.NfcA | NfcReaderFlags.NfcB | NfcReaderFlags.NfcF | NfcReaderFlags.NfcV | NfcReaderFlags.SkipNdefCheck, Bundle.Empty);
#endif
MediaAdded += mediaAdded;
MediaRemoved += mediaRemoved;
}
}
How could I replace the var activity = Forms.Context as Activity line to get the current activity and be able to call NfcAdapter?.EnableReaderMode without Xamarin Forms ?
Otherwise, is there another solution ?
It's include inside Xamarin.Essentials
Xamarin.Essentials.Platform.CurrentActivity
Essentials has been ported to .Net Maui
Platform.CurrentActivity
I ended up using this solution : https://gist.github.com/BrunoVT1992/8c858e4fed85d5dd96098c012a6e0708
using System.Collections.Generic;
using System.Linq;
using Android.Runtime;
using Android.Util;
using Java.Lang;
using Java.Util;
namespace Droid
{
public static class CurrentActivityUtil
{
/// <summary>
/// Gets the current activity of the application (must run on the UI thread for older Android versions).
/// </summary>
/// <returns>The current activity.</returns>
/// <param name="app">App.</param>
public static Activity GetCurrentActivity()
{
Activity activity = null;
List<Object> objects = null;
var activityThreadClass = Class.ForName("android.app.ActivityThread");
var activityThread = activityThreadClass.GetMethod("currentActivityThread").Invoke(null);
var activityFields = activityThreadClass.GetDeclaredField("mActivities");
activityFields.Accessible = true;
var obj = activityFields.Get(activityThread);
if (obj is JavaDictionary)
{
var activities = (JavaDictionary)obj;
objects = new List<Object>(activities.Values.Cast<Object>().ToList());
}
else if (obj is ArrayMap)
{
var activities = (ArrayMap)obj;
objects = new List<Object>(activities.Values().Cast<Object>().ToList());
}
else if (obj is IMap)
{
var activities = (IMap)activityFields.Get(activityThread);
objects = new List<Object>(activities.Values().Cast<Object>().ToList());
}
if (objects != null && objects.Any())
{
foreach (var activityRecord in objects)
{
var activityRecordClass = activityRecord.Class;
var pausedField = activityRecordClass.GetDeclaredField("paused");
pausedField.Accessible = true;
if (!pausedField.GetBoolean(activityRecord))
{
var activityField = activityRecordClass.GetDeclaredField("activity");
activityField.Accessible = true;
activity = (Activity)activityField.Get(activityRecord);
break;
}
}
}
return activity;
}
}
}

Why is this transform set in this Unity script?

I have been following this great tutorial:
https://www.youtube.com/watch?v=uxrKE2VKvmc
and at some point it does this for each target, it creates a gameObject ?
If you look at the code here:
private void SetupTargets(List<TrackableBehaviour> allTargets)
{
Debug.Log("Listing all Targets names:");
foreach (TrackableBehaviour target in allTargets)
{
Debug.Log("Target's name:" + target.TrackableName);
target.gameObject.transform.parent = transform;
target.gameObject.name = target.TrackableName;
target.gameObject.AddComponent<PlaneManager>();
Debug.Log(target.TrackableName + " created!");
}
}
why this line of code ?
target.gameObject.transform.parent = transform;
If I comment it out it still works fine..
The full class code is below:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;
using System.Linq;
public class TargetManager : MonoBehaviour
{
public String mStartingMarkerDatabaseName = "";
private List<TrackableBehaviour> mAllTargets = new List<TrackableBehaviour>();
private void Awake()
{
VuforiaARController.Instance.RegisterVuforiaStartedCallback(onVuforiaStarted);
}
private void onDestroy()
{
VuforiaARController.Instance.UnregisterVuforiaStartedCallback(onVuforiaStarted);
}
private void onVuforiaStarted()
{
LoadDatabase(mStartingMarkerDatabaseName);
mAllTargets = GetTargets();
SetupTargets(mAllTargets);
}
private void LoadDatabase(string name)
{
ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
objectTracker.Stop();
if (DataSet.Exists(name))
{
DataSet dataSet = objectTracker.CreateDataSet();
dataSet.Load(name);
objectTracker.ActivateDataSet(dataSet);
}
objectTracker.Start();
}
private List<TrackableBehaviour> GetTargets()
{
List<TrackableBehaviour> allTrackables = new List<TrackableBehaviour>();
allTrackables = TrackerManager.Instance.GetStateManager().GetTrackableBehaviours().ToList();
return allTrackables;
}
private void SetupTargets(List<TrackableBehaviour> allTargets)
{
Debug.Log("Listing all Targets names:");
foreach (TrackableBehaviour target in allTargets)
{
Debug.Log("Target's name:" + target.TrackableName);
target.gameObject.transform.parent = transform;
target.gameObject.name = target.TrackableName;
target.gameObject.AddComponent<PlaneManager>();
Debug.Log(target.TrackableName + " created!");
}
}
}
target.gameObject.transform.parent = transform;
That code means that the target gameObject will be a child of whatever gameObject the TargetManager script is attached to.
As derHugo pointed out in the comments, it's redundant and can just be written as
target.transform.parent = transform;

UWP WinRTXamlToolkit: chart-labels with units

For an UWP-app I'm displaying a chart with height data and it currently looks like this:
I'd like to have units for the y-values like 100 m, but I can only manage to get the value itself.
I am able to put a static unit behind that value by "StringFormat" in the "AxisLabelStyle" like this
<Setter Property="StringFormat" Value="{}{0:0 m}" />
but unfortunately I need a dynamic unit (e.g. meters or feet).
Am I missing anything? Ideas?
As we've discussed, this style is set by user. So I just use a ComboBox to select the style for test.
Here is my code:
<Charting:Chart x:Name="AreaChart" Title="Area Chart" Margin="0,0">
<Charting:AreaSeries x:Name="areaseries" IndependentValuePath="Value" DependentValuePath="Number" IsSelectionEnabled="True" />
</Charting:Chart>
<ComboBox x:Name="comboBox" VerticalAlignment="Bottom" SelectionChanged="comboBox_SelectionChanged">
<ComboBoxItem>Meters</ComboBoxItem>
<ComboBoxItem>Feet</ComboBoxItem>
</ComboBox>
code behind is just for testing, I didn't tried to rebuild your chart in your picture:
public MainPage()
{
this.InitializeComponent();
this.Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LoadChartContents();
}
private void LoadChartContents()
{
Random rand = new Random();
List<ChartTest> testitem = new List<ChartTest>();
for (int i = 0; i < 30; i++)
{
testitem.Add(new ChartTest() { Value = i, Number = rand.Next(0, 100) });
}
(AreaChart.Series[0] as AreaSeries).ItemsSource = testitem;
}
private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
areaseries.IndependentAxis = new LinearAxis { Orientation = AxisOrientation.X };
var axis = (LinearAxis)areaseries.IndependentAxis;
var item = comboBox.SelectedItem as ComboBoxItem;
if ((string)item.Content == "Meters")
{
var labelstyle = new Style(typeof(AxisLabel));
labelstyle.Setters.Add(new Setter(AxisLabel.StringFormatProperty, "{0:0 m}"));
axis.AxisLabelStyle = labelstyle;
}
else
{
var labelstyle = new Style(typeof(AxisLabel));
labelstyle.Setters.Add(new Setter(AxisLabel.StringFormatProperty, "{0:0 feet}"));
axis.AxisLabelStyle = labelstyle;
}
}
And my is ChartTest class like this:
public class ChartTest
{
public int Value { get; set; }
public int Number { get; set; }
}
The key point here is dynamic adding AxisLabelStyle to AreaSeries in the SelectionChanged event of the ComboBox.

Creating Objects from input file

I'm trying to somehow create objects by reading from a text file. However, I seem to be doing something wrong, and I can't put my finger on it.
Main:
import java.util.*;
import java.io.*;
public class Project2 {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner((new File("Project2DataFile.txt")));
sc.useDelimiter(",");
ArrayList<BaseballPlayer> myplayer = new ArrayList<BaseballPlayer>();
while (sc.hasNext()) {
String str = sc.nextLine();
for(int cnt = 0; cnt < 4; cnt++){
BaseballPlayer player = new BaseballPlayer();
if( player.batavg < 0 || player.batavg > 100 ){throw new IllegalArgumentException ("Illegal Batting Avg");}
player.pnumber = sc.nextInt();
player.lastname = sc.next();
player.firstname = sc.next();
player.batavg = sc.nextFloat();
}
continue;
}
System.out.println(myplayer);
}
Class:
public class BaseballPlayer {
public static int pnumber; // player number
public static String lastname; // player's last name
public static String firstname; // player's first name
public static float batavg; // player's batting average
}
And I might as well put the text file in there too:
48,deGrom,Jacob,.120
58,Mejia,Jenry,.140
49,Niese,Jon,.091
7,d'Arnaud,Travis,.324
21,Duda,Lucas,.237
4,Flores,Wilmner,.268
11,Tejada,Ruben,.345
5,Wright,David,.289
3,Granderson,Curtis,.327
12,Lagares,Juan,.298
It seems you are using static incorrectly. static is for members shared by all instances of a class, so you should not use it in BaseballPlayer. To fix the problem, you need to remove all statics in BaseballPlayer.

I'm stuck at slick graphics

I'm trying to make a game, using slick2d, and lwjgl. I don't get why this code doesn't work
firstStage.java
package net.CharlesDickenson;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class firstStage extends BasicGameState {
public bossVar bossChecker() {
if(isBeforeMiddleBoss) return bossVar.beforeBoss;
if(isMiddleBoss) return bossVar.Middle;
if(isBeforeBoss) return bossVar.beforeBoss;
if(isBoss) return bossVar.Boss;
return null;
}
#SuppressWarnings("static-access")
public firstStage(int state) {
this.state = state;
}
#Override
public void init(GameContainer _arg0, StateBasedGame _arg1)
throws SlickException {
scoreBoard = new Image("res/scoreBoard.png");
backs = new Image("res/1stageBack.gif");
isBeforeMiddleBoss = true;
isMiddleBoss = false;
isBeforeBoss = false;
isBoss = false;
_arg0.setShowFPS(false);
}
#Override
public void render(GameContainer arg0, StateBasedGame _arg1, Graphics _g)
throws SlickException {
this._g = _g;
new Mob().getGraphics(_g);//i passed graphics
new Char().getGraphics(_g);//i passed graphics
new Bullet().getGraphics(_g);//i passed graphics
_g.drawImage(scoreBoard, 550, 5);
_g.drawImage(backs, 10, 10);
_g.drawString(fps, 580, 570);
_g.drawString("High Score-> Not avaiable", 560, 60);
_g.drawString("Score-> " + currScore, 595, 80);
}
#Override
public void update(GameContainer _arg0, StateBasedGame _arg1, int arg2)
throws SlickException {
fps = "Frame Per Second-> " + _arg0.getFPS();
bossVar b = bossChecker();
switch(b) {
case beforeMiddle :
break;
case Boss :
break;
default:
break;
}
}
#SuppressWarnings("static-access")
#Override
public int getID() {
return this.state;
}
private static int state;
private static int currScore = 0;
private static final int originX = 270;
private static final int originY = 490;
public static int X = originX;
public static int Y = originY;
private static String fps;
private Image scoreBoard;
private Image backs;
private Graphics _g;
public boolean isBeforeMiddleBoss;
public boolean isMiddleBoss;
public boolean isBeforeBoss;
public boolean isBoss;
}
Char.java
package net.CharlesDickenson;
import org.lwjgl.input.Keyboard;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
public class Char extends Bullet implements Entity {
#Override
public void getGraphics(Graphics _g) {
this._g = _g;//so i got graphics, but
if(!isInit) return;
_g.drawImage(Char, getCharX(), getCharY());//this codes doesn't works.
}
#Override
public int getCharX() {
switch(VarTracker.stage) {
case 1:
return firstStage.X;
}
return 0;
}
#Override
public int getCharY() {
switch(VarTracker.stage) {
case 1:
return firstStage.Y;
}
return 0;
}
public void setCharX(int i) {
System.out.println("asdgagsd");
switch(VarTracker.stage) {
case 1:
firstStage.X += i;
}
}
public void setCharY(int i) {
System.out.println("asdgagsd");
switch(VarTracker.stage) {
case 1:
firstStage.Y += i;
}
}
#Override
public void update() {
if(!isInit) return;
_g.drawImage(Char, getCharX(), getCharY());//this code doesn't work, too.
up = Keyboard.isKeyDown(Keyboard.KEY_UP);
down = Keyboard.isKeyDown(Keyboard.KEY_DOWN);
left = Keyboard.isKeyDown(Keyboard.KEY_LEFT);
right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
z = Keyboard.isKeyDown(Keyboard.KEY_Z);
if(up && !shift) {
setCharY(6);
}
if(down && !shift) {
setCharY(-6);
}
if(left && !shift) {
setCharX(-6);
}
if(right && !shift) {
setCharX(6);
}
if(up && shift) {
setCharY(2);
}
if(down && shift) {
setCharY(-2);
}
if(left && shift) {
setCharX(-2);
}
if(right && shift) {
setCharX(2);
}
if(z) {
new Bullet().isFiring = true;
}
if(!z) {
new Bullet().isFiring = false;
}
}
#Override
public void init() {
System.out.println("<Char> Initializing...");
isInit = false;
try {
Char = new Image("res/char.png");
} catch (SlickException e) {
e.printStackTrace();
}
isInit = true;
System.out.println("<Char> Done with init()");
}
private boolean up;
private boolean down;
private boolean left;
private boolean right;
private boolean shift;
private boolean z;
private boolean isInit;
private Image Char;
private Graphics _g;
}
I passed graphics to other class using getGraphics method, to put a image, but it doesn't work.
at render method, it worked, but I can't put a image in other class.
The reason that it doesn't work is that you are using Graphics incorrectly. When Slick2d draws something, it uses the render method. This method is passed an instance of Graphics, to which you can draw stuff. When the call ends the Graphics object is no longer useful for anything. There is thus no reason to pass it to anything that doesn't use it immediately.
What you want to do is create a render method in your Mob, Char and Bullet classes. Make instances of said classes outside of the render method, for instance in init and store them in some data structure, for instance a List. In the render method, you simple traverse the list and call render or draw on each element. A quick example:
// Give the Entity interface two methods if they don't exist already:
public interface Entity {
void render(Graphics g);
void update(int delta);
}
// In firststage.java
List<Entity> list;
// In the init() method
public void init(GameContainer container, StateBasedGame game)
throws SlickException {
...
list = new ArrayList<Entity>();
list.add(new Mob());
list.add(new Char());
list.add(new Bullet());
}
// In the render method
public void render(GameContainer container, StateBasedGame game, Graphics g)
throws SlickException {
...
for (Entity e : list) {
e.draw(g);
}
}
// In the update method
public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException {
...
for (Entity e : list) {
e.update(delta);
}
}
TL;DR version: The Graphics object exists only to be drawn to in a single render call.
Render is called many times a second, so object creation in that method is not recommended.
Object oriented programming is good at modeling objects. Games tend to model a lot of objects. Make use of it.