How to make Generated gif in xamarin.ios slower? - c#

I created a service used in my xamarin.forms project to generate a gif from four downloaded frame. The android side is working good, but I got a problem in iOs side, where gif is created but it's too fast, regardless of the set delay value. This is my class:
public class GifService : IGifService
{
public string CreateGif(string frame1Path, string frame2Path, string frame3Path, string frame4Path,string webId,string path="")
{
List<UIImage> listOfFrame = new List<UIImage>();
UIImage image1 = new UIImage(frame1Path);
listOfFrame.Add(image1);
UIImage image2 = new UIImage(frame2Path);
listOfFrame.Add(image2);
UIImage image3 = new UIImage(frame3Path);
listOfFrame.Add(image3);
UIImage image4 = new UIImage(frame4Path);
listOfFrame.Add(image4);
NSMutableDictionary fileProperties = new NSMutableDictionary();
fileProperties.Add(CGImageProperties.GIFLoopCount, new NSNumber(0));
NSMutableDictionary frameProperties = new NSMutableDictionary();
frameProperties.Add(CGImageProperties.GIFDelayTime, new NSNumber(5f));
NSUrl documentsDirectoryUrl = NSFileManager.DefaultManager.GetUrl(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User,null, true,out _);
NSUrl fileUrl = documentsDirectoryUrl.Append(webId + ".gif",false);
var destination = CGImageDestination.Create(fileUrl, MobileCoreServices.UTType.GIF, 4);
destination.SetProperties(fileProperties);
foreach(var frame in listOfFrame)
{
var cgImage = frame.CGImage;
if(cgImage!= null)
{
destination.AddImage(cgImage, frameProperties);
}
}
if (!destination.Close())
{
Console.WriteLine("Failed to finalize the image destination");
}
return fileUrl.Path;
}
}
I think that the problem is CGImageProperties.GIFDelayTime that is ignored, but i don't know why. How can I resolve this problem?

After some tries, I found finally a solution to generate a gif with a desired delay. I don't know why, but in the way i showed in my question, the options are ignored.
Here a working solution:
public class GifService : IGifService
{
public string CreateGif(string frame1Path, string frame2Path, string frame3Path, string frame4Path,string webId,string path="")
{
List<UIImage> listOfFrame = new List<UIImage>();
UIImage image1 = new UIImage(frame1Path);
listOfFrame.Add(image1);
UIImage image2 = new UIImage(frame2Path);
listOfFrame.Add(image2);
UIImage image3 = new UIImage(frame3Path);
listOfFrame.Add(image3);
UIImage image4 = new UIImage(frame4Path);
listOfFrame.Add(image4);
NSMutableDictionary fileProperties = new NSMutableDictionary
{
{ CGImageProperties.GIFLoopCount, new NSNumber(1) }
};
NSUrl documentsDirectoryUrl = NSFileManager.DefaultManager.GetUrl(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User,null, true,out _);
NSUrl fileUrl = documentsDirectoryUrl.Append(webId + ".gif",false);
var destination = CGImageDestination.Create(fileUrl, MobileCoreServices.UTType.GIF, 4);
destination.SetProperties(fileProperties);
foreach (var frame in listOfFrame)
{
//difference is here, i create a var option and i set the
//GifDictionary
var options = new CGImageDestinationOptions();
options.GifDictionary = new NSMutableDictionary();
options.GifDictionary[CGImageProperties.GIFDelayTime] = new NSNumber(1f);
var cgImage = frame.CGImage;
if(cgImage!= null)
{
destination.AddImage(cgImage, options);
}
}
if (!destination.Close())
{
Console.WriteLine("Failed to finalize the image destination");
}
return fileUrl.Path;
}
}

Related

How to get drawable path?

public async Task<List<AppItem>> GetAndroidApps()
{
try
{
var apps = Android.App.Application.Context.PackageManager.GetInstalledApplications(PackageInfoFlags.MatchAll);
foreach(var item in apps)
{
string packageName = item.PackageName;
string appName = item.LoadLabel(Android.App.Application.Context.PackageManager);
var appIcon = item.LoadIcon(Android.App.Application.Context.PackageManager).ToString();
System.Diagnostics.Debug.WriteLine($"{appIcon}; {appName}; {packageName};");
}
return null;
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
}
How I can get appIcon path to display it?
I can't get full path to other app icon...
Thank you!
Best wishes!
You could load the icon from the drawable resource identifier (in the package's resources) of this component's. And set the imagesource for imageview.
I use my App6 for example to load the icon. It works.
var apps = Android.App.Application.Context.PackageManager.GetInstalledApplications(PackageInfoFlags.MatchAll);
foreach (var item in apps)
{
string packageName = item.PackageName;
string appName = item.LoadLabel(Android.App.Application.Context.PackageManager);
if (packageName == "com.companyname.app6")
{
var appIcon = item.LoadIcon(Android.App.Application.Context.PackageManager).ToString();
var image = item.Icon;
imageView.SetImageResource(image);
}
//System.Diagnostics.Debug.WriteLine($"{appIcon}; {appName}; {packageName};");
}
Updated:
You could use the DependentService to do that.
I convet the resID of deawable to bitmap and then convert the bitmap to stream. At last, i set the image source form the stream in Xamarin.forms.
Create the interface in Xamarin.forms.
public interface GetIcon
{
byte[] GetIconFromApp();
}
Implementation in Android:
[assembly: Dependency(typeof(GetIconFromApp_Android))]
namespace App13.Droid
{
class GetIconFromApp_Android : GetIcon
{
public byte[] GetIconFromApp()
{
var apps = Android.App.Application.Context.PackageManager.GetInstalledApplications(PackageInfoFlags.MatchAll);
byte[] bitmapData=null;
foreach (var item in apps)
{
string packageName = item.PackageName;
string appName = item.LoadLabel(Android.App.Application.Context.PackageManager);
if (packageName == "com.companyname.app6")
{
var appIcon = item.LoadIcon(Android.App.Application.Context.PackageManager).ToString();
var imageID = item.Icon;
// Converting Drawable Resource to Bitmap
var bitmap = BitmapFactory.DecodeResource(Forms.Context.Resources, imageID);
//comver bitmap to byte
using (var stream = new MemoryStream())
{
bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
}
}
return bitmapData;
}
}
}
Platform implementations with button click event.
private void Button_Clicked(object sender, EventArgs e)
{
var ImageByteArray = DependencyService.Get<GetIcon>().GetIconFromApp();
image.Source = ImageSource.FromStream(() => new MemoryStream(ImageByteArray, 0, ImageByteArray.Length));
}
Screenshot:

How to save a photo with GPS data intact in iOS 13.4.1 using Xamarin?

It would appear that something has changed in recent versions of iOS as it relates to saving GPS data in photos and subsequent to a bug in the Xam.Plugin.Media library, I am attempting to figure out how to take a photo and save it to the Photo Gallery with intact GPS data using iOS 13.4.1 and Xamarin.iOS 13.16.0.13. I have looked at the internals of Xam.Plugin.Media and using this as a starting point, tried to cobble something together on the hunch that because Xam.Plugin.Media uses ALAssetsLibrary to save to the Photo Gallery, perhaps this was why the GPS data is not being saved with the photo.
I am currently at the point where I had thought I would be able to take the photo, merge GPS data into the file and save the JPG output to a temporary location in the app folder (i.e. I haven't even gotten to saving the photo to the gallery yet). But when I examine this temp file using either the Preview app on MacOS or Photoshop to view the GPS metadata, the data is not there.
My handler for UIImagePickerController.FinishedPickingMedia is this:
private void OnFinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e)
{
try
{
NSDictionary info = e.Info;
NSDictionary meta = null;
UIImage image = null;
string savedImagePath = null;
if (_imagePicker.SourceType == UIImagePickerControllerSourceType.Camera)
{
meta = (NSDictionary)info[UIImagePickerController.MediaMetadata];
image = (UIImage)info[UIImagePickerController.OriginalImage];
if (meta != null && meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
{
var newMeta = new NSMutableDictionary();
newMeta.SetValuesForKeysWithDictionary(meta);
var newTiffDict = new NSMutableDictionary();
newTiffDict.SetValuesForKeysWithDictionary(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
newTiffDict.SetValueForKey(meta[ImageIO.CGImageProperties.Orientation], ImageIO.CGImageProperties.TIFFOrientation);
newMeta[ImageIO.CGImageProperties.TIFFDictionary] = newTiffDict;
meta = newMeta;
}
if (_locationPermissionGranted)
{
meta = SetGpsLocation(meta);
}
savedImagePath = SaveImageWithMetadata(image, meta);
}
string aPath = null;
if (_imagePicker.SourceType != UIImagePickerControllerSourceType.Camera)
{
// Try to get the album path's URL.
var url = (NSUrl)info[UIImagePickerController.ReferenceUrl];
aPath = url?.AbsoluteString;
}
}
catch (Exception ex)
{
Console.WriteLine($"Unable to get metadata: {ex}");
}
}
Which calls:
private NSDictionary SetGpsLocation(NSDictionary meta)
{
var newMeta = new NSMutableDictionary();
newMeta.SetValuesForKeysWithDictionary(meta);
var newGpsDict = new NSMutableDictionary();
newGpsDict.SetValueForKey(new NSNumber(Math.Abs(_lat)), ImageIO.CGImageProperties.GPSLatitude);
newGpsDict.SetValueForKey(new NSString(_lat > 0 ? "N" : "S"), ImageIO.CGImageProperties.GPSLatitudeRef);
newGpsDict.SetValueForKey(new NSNumber(Math.Abs(_long)), ImageIO.CGImageProperties.GPSLongitude);
newGpsDict.SetValueForKey(new NSString(_long > 0 ? "E" : "W"), ImageIO.CGImageProperties.GPSLongitudeRef);
newGpsDict.SetValueForKey(new NSNumber(_altitude), ImageIO.CGImageProperties.GPSAltitude);
newGpsDict.SetValueForKey(new NSNumber(0), ImageIO.CGImageProperties.GPSAltitudeRef);
newGpsDict.SetValueForKey(new NSNumber(_speed), ImageIO.CGImageProperties.GPSSpeed);
newGpsDict.SetValueForKey(new NSString("K"), ImageIO.CGImageProperties.GPSSpeedRef);
newGpsDict.SetValueForKey(new NSNumber(_direction), ImageIO.CGImageProperties.GPSImgDirection);
newGpsDict.SetValueForKey(new NSString("T"), ImageIO.CGImageProperties.GPSImgDirectionRef);
newGpsDict.SetValueForKey(new NSString(_timestamp.ToString("hh:mm:ss")), ImageIO.CGImageProperties.GPSTimeStamp);
newGpsDict.SetValueForKey(new NSString(_timestamp.ToString("yyyy:MM:dd")), ImageIO.CGImageProperties.GPSDateStamp);
newMeta[ImageIO.CGImageProperties.GPSDictionary] = newGpsDict;
return newMeta;
}
private string SaveImageWithMetadata(UIImage image, NSDictionary meta)
{
string outputPath = null;
try
{
var finalQuality = 1.0f;
var imageData = image.AsJPEG(finalQuality);
// Continue to move down quality, rare instances.
while (imageData == null && finalQuality > 0)
{
finalQuality -= 0.05f;
imageData = image.AsJPEG(finalQuality);
}
if (imageData == null)
{
throw new NullReferenceException("Unable to convert image to jpeg, please ensure file exists or " +
"lower quality level");
}
var dataProvider = new CGDataProvider(imageData);
var cgImageFromJpeg = CGImage.FromJPEG(dataProvider, null, false, CGColorRenderingIntent.Default);
var imageWithExif = new NSMutableData();
var destination = CGImageDestination.Create(imageWithExif, UTType.JPEG, 1);
var cgImageMetadata = new CGMutableImageMetadata();
var destinationOptions = new CGImageDestinationOptions();
if (meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
{
destinationOptions.Dictionary[ImageIO.CGImageProperties.Orientation] =
meta[ImageIO.CGImageProperties.Orientation];
}
if (meta.ContainsKey(ImageIO.CGImageProperties.DPIWidth))
{
destinationOptions.Dictionary[ImageIO.CGImageProperties.DPIWidth] =
meta[ImageIO.CGImageProperties.DPIWidth];
}
if (meta.ContainsKey(ImageIO.CGImageProperties.DPIHeight))
{
destinationOptions.Dictionary[ImageIO.CGImageProperties.DPIHeight] =
meta[ImageIO.CGImageProperties.DPIHeight];
}
if (meta.ContainsKey(ImageIO.CGImageProperties.ExifDictionary))
{
destinationOptions.ExifDictionary =
new CGImagePropertiesExif(meta[ImageIO.CGImageProperties.ExifDictionary] as NSDictionary);
}
if (meta.ContainsKey(ImageIO.CGImageProperties.TIFFDictionary))
{
destinationOptions.TiffDictionary =
new CGImagePropertiesTiff(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
}
if (meta.ContainsKey(ImageIO.CGImageProperties.GPSDictionary))
{
destinationOptions.GpsDictionary =
new CGImagePropertiesGps(meta[ImageIO.CGImageProperties.GPSDictionary] as NSDictionary);
}
if (meta.ContainsKey(ImageIO.CGImageProperties.JFIFDictionary))
{
destinationOptions.JfifDictionary =
new CGImagePropertiesJfif(meta[ImageIO.CGImageProperties.JFIFDictionary] as NSDictionary);
}
if (meta.ContainsKey(ImageIO.CGImageProperties.IPTCDictionary))
{
destinationOptions.IptcDictionary =
new CGImagePropertiesIptc(meta[ImageIO.CGImageProperties.IPTCDictionary] as NSDictionary);
}
destination.AddImageAndMetadata(cgImageFromJpeg, cgImageMetadata, destinationOptions);
var success = destination.Close();
if (success)
{
outputPath = GetOutputPath();
imageWithExif.Save(outputPath, true);
}
}
catch (Exception e)
{
Console.WriteLine($"Unable to save image with metadata: {e}");
}
return outputPath;
}
private static string GetOutputPath()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "temp");
Directory.CreateDirectory(path);
var timestamp = DateTime.UtcNow.ToString("yyyMMdd_HHmmss", CultureInfo.InvariantCulture);
var name = "IMG_" + timestamp + ".jpg";
return Path.Combine(path, GetUniquePath(path, name));
}
private static string GetUniquePath(string path, string name)
{
var ext = Path.GetExtension(name);
name = Path.GetFileNameWithoutExtension(name);
var fullName = name + ext;
var i = 1;
while (File.Exists(Path.Combine(path, fullName)))
{
fullName = name + "_" + (i++) + ext;
}
return Path.Combine(path, fullName);
}
The file is saved successfully, but without the expected GPS metadata. Which leads me to believe that the problem may be to do with the way I am saving the temporary photo or saving the GPS metadata to it in either SaveImageWithMetadata or SetGpsLocation.
If anyone can provide some info on what actually works now with iOS 13.4.1 and saving GPS data to photos, I would be very appreciative.

Unable to capture screen of WkWebView in Xamarin IOS

I am trying to capture the screen in IOS, Other than WkWebview all other view component I am able to capture by below code.WkWebview is giving a blank page as captured data. If I am using UIWebview the same code working Is there anything specific to do to take screen shot WkWebView.
Code for screen capture.
public static UIImage SnapshotView(this UIView view)
{
UIGraphics.BeginImageContextWithOptions(view.Bounds.Size, false, UIScreen.MainScreen.Scale);
view.DrawViewHierarchy(view.Bounds, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
WkWebView Configuration:
WKWebView _wkWebView = new WKWebView(ReaderView.Frame, new WKWebViewConfiguration());
_wkWebView.LoadFileUrl(tempUrl, tempUrl);
_wkWebView.ContentMode = UIViewContentMode.ScaleToFill;
_wkWebView.BackgroundColor = UIColor.Clear;
_wkWebView.Opaque = false;
_wkWebView.ScrollView.BackgroundColor = UIColor.Clear;
//_wkWebView.DrawViewHierarchy(_wkWebView.Bounds, true);
ReaderView.AddSubview(_wkWebView);
var imag = _wkWebView.SnapshotView();
I fixed the issue by replacing the WKWebView with PdfView.I am using this view for loading PDFs.
The latest code is below
pdfView = new PdfView();
pdfView.TranslatesAutoresizingMaskIntoConstraints = false;
ReaderView.AddSubview(pdfView);
pdfView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor).Active = true;
pdfView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor).Active = true;
pdfView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor).Active = true;
pdfView.BottomAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.BottomAnchor).Active = true;
// var path = Bundle.main.url(forResource: "test", withExtension: "pdf") else { return }
PdfDocument document;
// PdfDocument
using (urlString = new NSString(FilePath))
using (var tempUrl = NSUrl.CreateFileUrl(new string[] { urlString }))
document = new PdfDocument(tempUrl);
//if var document = PdfDocument(url: path) {
pdfView.Document = document;

acumatica import items with image API

Now I have successfully working code (with multiple threads) for items bulk import in IN202500 screen in Acumatica.
The problem is that I am struggling to import an image of an item and actually I don't have an image by itself but only URL link to this image.
So, my question is has anyone done this in c#?
This is my piece of code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ItemImportMultiThreaded
{
public class ItemImporter
{
private IN202500.Screen _itemsScreen;
private static object _itemsSchemaLock = new object();
private static IN202500.Content _itemsSchema;
public void Login(string url, string username, string password, string company)
{
Console.WriteLine("[{0}] Logging in to {1}...", System.Threading.Thread.CurrentThread.ManagedThreadId, url);
_itemsScreen = new IN202500.Screen();
_itemsScreen.Url = url + "/PMSDB/(W(2))/Soap/IN202500.asmx";
_itemsScreen.EnableDecompression = true;
_itemsScreen.CookieContainer = new System.Net.CookieContainer();
_itemsScreen.Timeout = 36000;
_itemsScreen.Login(username, password);
Console.WriteLine("[{0}] Logged in to {1}.", System.Threading.Thread.CurrentThread.ManagedThreadId, url);
lock (_itemsSchemaLock)
{
// Threads can share the same schema.
if (_itemsSchema == null)
{
Console.WriteLine("[{0}] Retrieving IN202500 schema...", System.Threading.Thread.CurrentThread.ManagedThreadId);
_itemsSchema = _itemsScreen.GetSchema();
if (_itemsSchema == null) throw new Exception("IN202500 GetSchema returned null. See AC-73433.");
}
}
}
public void Logout()
{
_itemsScreen.Logout();
}
public void Import(List<Item> items)
{
Console.WriteLine("[{0}] Submitting {1} items to Acumatica...", System.Threading.Thread.CurrentThread.ManagedThreadId, items.Count);
var commands = new IN202500.Command[]
{
_itemsSchema.StockItemSummary.InventoryID,
_itemsSchema.StockItemSummary.Description,
_itemsSchema.GeneralSettingsItemDefaults.ItemClass,
_itemsSchema.VendorDetails.VendorID,
_itemsSchema.VendorDetails.VendorInventoryID,
_itemsSchema.VendorDetails.ServiceCommands.NewRow,
_itemsSchema.VendorDetails.VendorID,
_itemsSchema.VendorDetails.VendorInventoryID,
_itemsSchema.VendorDetails.ServiceCommands.NewRow,
_itemsSchema.VendorDetails.VendorID,
_itemsSchema.VendorDetails.VendorInventoryID,
_itemsSchema.CrossReference.AlternateID,
_itemsSchema.CrossReference.Description,
_itemsSchema.Actions.Save
};
string[][] data = new string[items.Count][];
int count = 0;
foreach(Item item in items)
{
data[count] = new string[11];
data[count][0] = item.InventoryID;
data[count][1] = item.Description.Trim();
data[count][2] = item.ItemClassID;
data[count][3] = item.DigiKey;
data[count][4] = item.DKPN;
data[count][5] = item.Mouser;
data[count][6] = item.MouserID;
data[count][7] = item.Element14;
data[count][8] = item.Element14ID;
data[count][9] = item.AlternateID;
data[count][10] = item.Descr;
count++;
}
_itemsScreen.Import(commands, null, data, false, true, true);
Console.WriteLine("[{0}] Submitted {1} items to Acumatica.", System.Threading.Thread.CurrentThread.ManagedThreadId, items.Count);
}
}
}
I tried to use FileStream but that didn't work.
If by URL link you mean an external http resource, you can download the image and upload it.
The StockItems image field cycle through all the images contained in the Files popup in the order they are displayed:
I uploaded the images from a static external Url using the following code:
const string imageUrl = "https://cdn.acumatica.com/media/2016/03/software-technology-industries-small.jpg";
string path = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetTempFileName(), ".jpg"));
// Download Image
using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(imageUrl), path);
}
// ReadUploadFile function below
byte[] data = ReadUploadFile(path);
_itemsScreen.Import(new IN202500.Command[]
{
// Get Inventory Item
new Value
{
Value = "D1",
LinkedCommand = _itemsSchema.StockItemSummary.InventoryID,
},
_itemsSchema.Actions.Save,
// Upload Inventory Item Image
new Value
{
FieldName = Path.GetFileName(path),
LinkedCommand = _itemsSchema.StockItemSummary.ServiceCommands.Attachment
},
_itemsSchema.Actions.Save
},
null,
new string[][]
{
new string[]
{
// Image data
Convert.ToBase64String(data)
}
},
false,
false,
true);
public byte[] ReadUploadFile(string filePath)
{
byte[] filedata;
using (FileStream file = File.Open(filePath,
FileMode.Open,
FileAccess.ReadWrite,
FileShare.ReadWrite))
{
filedata = new byte[file.Length];
file.Read(filedata, 0, filedata.Length);
}
if (filedata == null || filedata.Length == 0)
{
throw new Exception(string.Concat("Invalid or empty file: ", filePath));
}
return filedata;
}
You can try using the below, Tested Code.
var content = _context.CR306000GetSchema(); _context.CR306000Clear();
var commands = new List();
ReqParameter(content, ref commands);
commands.Add(content.Actions.Save);
commands.Add(content.CaseSummary.CaseID);
var orderResults = _context.CR306000Submit(commands.ToArray());
private static void ReqParameter(CR306000Content content, ref List cmds) { if (cmds == null) throw new ArgumentNullException("cmds");
private static void ReqParameter(CR306000Content content, ref List<Command> cmds)
{
if (cmds == null) throw new ArgumentNullException("cmds");
byte[] filedata= null;
Uri uri = new Uri("https://cdn.acumatica.com/media/2016/03/software-technology-industries-small.jpg"); // change the required url of the data that has to be fetched
if (uri.IsFile)
{
string filename = System.IO.Path.GetFileName(uri.LocalPath);
filedata = System.Text.Encoding.UTF8.GetBytes(uri.LocalPath);
}
if (filedata == null)
{
WebClient wc = new WebClient();
filedata = wc.DownloadData(uri);
}
cmds = new List<Command>
{
//Case Header Details
new Value { Value="<NEW>",LinkedCommand = content.CaseSummary.CaseID},
new Value { Value="L41",LinkedCommand = content.CaseSummary.ClassID},
new Value { Value="ABCSTUDIOS",LinkedCommand = content.CaseSummary.BusinessAccount, Commit = true},
new Value { Value="Test subject created from envelop call 11C",LinkedCommand = content.CaseSummary.Subject},
// body of the case
new Value{Value= "Body of the content for created through envelop call 11B", LinkedCommand = content.Details.Description},
//Attaching a file
new Value
{
Value = Convert.ToBase64String(filedata), // byte data that is passed to through envelop
FieldName = "Test.jpg",
LinkedCommand =
content.CaseSummary.ServiceCommands.Attachment
},
};
}
Let me know if this works for you.
Thanks

route line does not appear using MkMap in xamarin ios

i want to draw route line using mkMap in xamarin ios. my code is working correctly but it does not show route line between points. my code is given below
my first picture shows the starting annotation point and second picture shows ending annotation point
MapView Code:
private MKMapView _map;
private MapDelegate _mapDelegate;
public QiblaCompassVC (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
_map = new MKMapView(mapsView.Bounds)
{
MapType = MKMapType.Standard,
ShowsUserLocation = true,
ZoomEnabled = true,
ScrollEnabled = true
};
//_map = new MKMapView(mapsView.Bounds);
// _map.ShowsUserLocation = true;
_mapDelegate = new MapDelegate();
_map.Delegate = _mapDelegate;
//mapsView.Add(_map);
View = _map;
var target = new CLLocationCoordinate2D(30.3753, 69.3451);
var viewPoint = new CLLocationCoordinate2D(21.3891, 39.8579);
var annotation = new mapAnnotation(new CLLocationCoordinate2D(30.3753, 69.3451), "Pakistan", "Countery of love");
_map.AddAnnotation(annotation);
var annotation1 = new mapAnnotation(new CLLocationCoordinate2D(21.3891, 39.8579), "Makka", "Allah home");
_map.AddAnnotation(annotation1);
var camera = MKMapCamera.CameraLookingAtCenterCoordinate(target, viewPoint, 500);
_map.Camera = camera;
createRoute();
//CLLocationCoordinate2D coords = new CLLocationCoordinate2D(30.3753, 69.3451);
//MKCoordinateSpan span = new MKCoordinateSpan(MilesToLatitudeDegrees(20), MilesToLongitudeDegrees(20, coords.Latitude));
//_map.Region = new MKCoordinateRegion(coords, span);
}
public void createRoute()
{
var dict = new NSDictionary();
var orignPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(30.3753, 69.3451), dict);
var sourceItem = new MKMapItem(orignPlaceMark);
//End at Xamarin Cambridge Office
var destPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(21.3891, 39.8579), dict);
var destItem = new MKMapItem(destPlaceMark);
var request = new MKDirectionsRequest
{
Source = sourceItem,
Destination = destItem,
RequestsAlternateRoutes = true,
};
var directions = new MKDirections(request);
directions.CalculateDirections((response, error) =>
{
if (error != null)
{
Console.WriteLine(error.LocalizedDescription);
}
else
{
//Add each Polyline from route to map as overlay
foreach (var route in response.Routes)
{
_map.AddOverlay(route.Polyline);
}
}
});
}
MapDelegate Code:
class MapDelegate : MKMapViewDelegate
{
public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
{
if (overlay is MKPolyline)
{
var route = (MKPolyline)overlay;
var renderer = new MKPolylineRenderer(route) { StrokeColor = UIColor.Blue };
return renderer;
}
return null;
}
public override MKOverlayView GetViewForOverlay(MKMapView mapView, IMKOverlay overlay)
{
if (overlay is MKPolyline)
{
// return a view for the polygon
MKPolyline l_polyline = overlay as MKPolyline;
MKPolylineView l_polylineView = new MKPolylineView(l_polyline);
MKPolylineRenderer l_polylineRenderer = new MKPolylineRenderer(l_polyline);
l_polylineView.FillColor = UIColor.Blue;
l_polylineView.StrokeColor = UIColor.Red;
return l_polylineView;
}
return null;
}
}
The problem is in the GetViewForOverlay method,
The overlay parameter is not not of type MKPolyline, it is a wrapper containing the MKPolyline, this is how to get it :
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
{
var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
...
}
Source from xamarin forum

Categories

Resources