I have an array of country names and wish to place them on a MKMapView as Placemarks. So for example if France is in the countryName array I would like a pin placed on the center of France.
Is there a way of doing this without having the lat/long stored for each country?
I would like to make this work offline and only require the map in its most basic and fully zoomed out image of the world.
I believe MKMapView holds some basic geo information so is the above possible without the use of GLGeocoder and a internet connection?
try this function for get latitude and longitude for address:-(if you use only country name then we get center lat nag long for that country)
-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) countryStr {
NSString *urlAddressStr = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[countryStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlAddressStr]];
NSArray *items = [locationStr componentsSeparatedByString:#","];
double lat = 0.0;
double long = 0.0;
if([items count] >= 4 && [[items objectAtIndex:0] isEqualToString:#"200"])
{
lat = [[items objectAtIndex:2] doubleValue];
long = [[items objectAtIndex:3] doubleValue];
}
CLLocationCoordinate2D location;
location.latitude = lat;
location.longitude = long;
return location;
}
after you get latitude and longitude
1)add use the mapKit Framework
3)set latitude and longitude on region
3) use this function
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id )annotation
This method will not work unless you store the data file (sqlite) into the application and query the database as you place the pins into the map. But it will guarantee the map data availability in offline mode.
Basically you can make use of the shape file available
http://thematicmapping.org/downloads/world_borders.php
Import it as sqlite file using the .loadshp command described
http://www.gaia-gis.it/gaia-sins/spatialite-tutorial-2.3.1.html
Once you have imported the sqlite file, you can just query something like
select lon,lat from world_borders where name like 'Zambia';
where
lon = longitude,
lat = latitude,
world_borders = table name
and 'Zambia' = country name.
Related
I have the following code n i have 4 records in data base but loop is running 2 times n getting only first row two times whats a problem in my code?
- (void) getAllRowsFromTableName:(NSString *)tableName{
NSString *qsql = [NSString stringWithFormat:#"SELECT * FROM '%#'",tableName];
NSLog(#"query is :%#",qsql);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db,[qsql UTF8String] , -1, &statement,nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSLog(#"loop");
int catId = sqlite3_column_int(statement, 1);
NSLog(#"***CatId is :%d",catId);
sqlite3_finalize(statement);
}
sqlite3_finalize(statement);
}
Wow! Another that use sqllite3 natively!! :)
I would suggest you an external lib (2 files) named FMDB, that is a wrapper to sqllite3.
https://github.com/ccgus/fmdb
Easy to use. Hope this helps.
Just to complete and close this question I am putting my comment in answer.
Try with commenting the sqlite3_finalize(statement); inside the while loop.
Explaination:
SQLite.org says
The sqlite3_finalize() function is called to delete a prepared
statement.
Also,
The application must finalize every prepared statement in order to
avoid resource leaks. It is a grievous error for the application to
try to use a prepared statement after it has been finalized. Any use
of a prepared statement after it has been finalized can result in
undefined and undesirable behavior such as segfaults and heap
corruption.
Thanks,
Is it possible to read or write to plist when the application is in background state?
It is not possible to read your plist when your application is in the background, because your application is not running more than 10 minutes in the background state. There are only three options for keeping your application running more than 10 minutes in the background.
If you want to read and write your plist, do this when your application comes to the foreground state. For this you can read and write your plist in the application became active delegate method.
try this one..
- (void)readPlist
{
NSString *filePath = #"/System/Library/CoreServices/SystemVersion.plist";
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSString *value;
value = [plistDict objectForKey:#"ProductVersion"];
/* You could now call the string "value" from somewhere to return the value of the string in the .plist specified, for the specified key. */
}
- (void)writeToPlist
{
NSString *filePath = #"/System/Library/CoreServices/SystemVersion.plist";
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
[plistDict setValue:#"1.1.1" forKey:#"ProductVersion"];
[plistDict writeToFile:filePath atomically: YES];
/* This would change the firmware version in the plist to 1.1.1 by initing the NSDictionary with the plist, then changing the value of the string in the key "ProductVersion" to what you specified */
}
Hope this helps you!
i want the solution of below question, i dont know how to store sinup information in Plist, can any one knows please help.
Thanks in advance
Use Dummy data but the dummy data must not be in the code ,it should either be in an external file (plist/xml) or in a separate constant file.This improves the code management.
All screens must comply to Portrait and Landscape View Mode
1. The App will begin with the Login Screen, The screen should be having same functionality as any website.
a. Login
b. Sign Up
c. Maximum Tries (3) then lock the app
d. Requires Answer to secret question to unlock which will be accepted in sign up
If you are looking for storing small data like user credentials look for NSUserDefault.
For automatic login, if the user has logged in previously look this.
You can create a new .plist file to store the information.
Add New File in your project, of type "Property list". Its under the "Resource tab", on "Mac OS X" in the left pane of your xcode.
Once created, Now add new items in to it. The "Key" will be used the retrieve the value through the coding.
To retrieve the values in the coding, from .plist file, you can use this code:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* defaultSettings = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"YOUR_PLIST_FILE_NAME.plist" ofType:nil]];
[defaults registerDefaults:defaultSettings];
NSString *sName = [defaultSettings objectForKey:#"Name"]; //the Name is the Key in .plist file, so its corresponding value will be fetched and store in sName variable
NSString *defaultDomain = [defaultSettings objectForKey:#"domain"];
I hope it helps :)
I am not able to see the Blue current location dot when I use custom annotations
- (MKAnnotationView *) mapView:(MKMapView *) mapView viewForAnnotation:(id<MKAnnotation> ) annotation {
MKAnnotationView *customAnnotationView=[[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil] autorelease];
UIImage *pinImage = [UIImage imageNamed:#"ann.png"];
[customAnnotationView setImage:pinImage];
customAnnotationView.canShowCallout = YES;
//UIImageView *leftIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ann.png"]];
//customAnnotationView.leftCalloutAccessoryView = leftIconView;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
customAnnotationView.rightCalloutAccessoryView = rightButton;
return customAnnotationView;
}
if (annotation == map.userLocation) {
return nil;
}
Add this.:d
I got the answer now. Just need to add the following lines to the above code at the end just before return customAnnotationView;
if (annotation ==
mapView.userLocation) {
NSLog(#"nil"); return nil; }
thanks :)
The visibility of the current user location "blue dot" is unrelated to custom annotations. To make the user's current location show, you need to set the showsUserLocation property of your MKMapView to YES. For example:
yourMapView.showsUserLocation = YES;
or:
[yourMapView showsUserLocation] = YES;
Understand that there is a quirk in the way MapKit displays the current user location: in the simulator the UserLocation will always be Apple's headquarters in Cupertino, CA, USA. It will work fine on the device, however.
Edited to add:
As Terente points out, you do have to be careful not to "eat" the user's location annotation, and so must test to see if the annotation you're processing is the user's location. I wrap the logic with:
if ([annotation isKindOfClass:[MapLocation class]]) {
}
Where MapLocation is my annotation class.
UPDATE2 I think I found the true source of the leaks. I had some business objects that have string properties I forgot to release. These string properties were copied from my custom xlm node object, created here (KGYXMLNode) I don't understandt why the leak is reported here instead of my custom class. My NSString properties were copy and not retain.
UPDATE: I think it was a bug in Instruments or something or it doesn't magically leak anymore, but since xcode 4 it doesn't show this leak.
Hello, according to instruments i have a leak in the following code. I've built an objective-c wrapper around certain libxml functions to be able to parse xml docs using xpath, and in this method I'm setting the innerText for my custom node object.
-(void) SetInnerTextForNode: (xmlNodePtr) node : (KGYXMLNode *) obcNode
{
if ((node) && (node->children))
{
for (xmlNodePtr pnode = node->children; pnode != NULL; pnode = pnode->next)
{
if (pnode->type == XML_TEXT_NODE)
{
xmlChar *content = pnode->content;
NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content];
NSString *trimmedText = [innerText stringByTrimmingCharactersInSet: trimCharSet];
if (trimmedText.length > 0)
obcNode.innerText = trimmedText;
[innerText release];
break;
}
}
}
}
The leak is NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content];. I don't know what is wrong.
You shouldn't access a node's content directly, instead use xmlNodeGetContent:
xmlChar *content = xmlNodeGetContent(pnode);
NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content];
NSString *trimmedText = [innerText stringByTrimmingCharactersInSet: trimCharSet];
if (trimmedText.length > 0)
obcNode.innerText = trimmedText;
[innerText release];
// you must free what xmlNodeGetContent returns!
xmlFree(content);
break;
I don't know why your code is leaking, but it seems to me that you have an unsafe assignment of an autoreleased object to obcNode.innerText without retaining it.
This is a bit of a guess, but I think your dealloc method for obcnode does not release its innerText instance variable on deallocation. At first glance, your code fragment looks fine for memory management and that is the only potential error I can see.
The reason why it would be flagging the leak for innerText is possibly that trimmedText uses the same underlying unichar array as innerText but with different start and length values and therefore it retains innerText to stop the unichar array from going away.
Because trimmedText is an immutable string, sending copy to it merely causes it to send retain to itself and return itself, so obcNode owns trimmedText which owns innerText.