Показать данные кмл? Нет, вместо этого Карта собирается в местоположение (0,0) - PullRequest
1 голос
/ 31 октября 2011

Я использую код в этом вопросе NSURLConnection скачать большой файл (> 40 МБ) , чтобы загрузить файл KML и загрузить данные в мой MKMap с помощью KMLViewer из файлов Apple.С KMLViewer все в порядке. Код, приведенный в вопросе, тоже должен подойти, за исключением того факта, что когда я нажимаю кнопку (это должно сделать запрос URL, а затем загрузить данные на карту), карта просто переходит в местоположение 0, 0, масштабирование очень велико, и все, что я могу видеть, это черная карта. Что идет не так?Что я должен делать?Вот код: (Кстати, у меня есть два соединения, потому что одно использует JSON для получения результатов поиска Google для местоположений из UIsearchBar.)

РЕДАКТИРОВАТЬ 1

//In the ViewController.m
-(void) searchCoordinatesForAddress:(NSString *)inAddress //for Google location search
{
NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@?output=json",inAddress];

[urlString setString:[urlString stringByReplacingOccurrencesOfString:@" " withString:@"+"]];

NSURL *url = [NSURL URLWithString:urlString];

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

[connection release];
[request release];
}


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[webData setLength:0]; //webData in the header file
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if ( connection = theConnection ) //theConnection is created before
{
[webData appendData:data];
}
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSDictionary *results = [jsonString JSONValue];

NSArray *placemark = [results objectForKey:@"Placemark"];
NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"];

double longitude = [[coordinates objectAtIndex:0] doubleValue];
double latitude = [[coordinates objectAtIndex:1] doubleValue];

NSLog(@"Latitude - Longitude: %f %f", latitude, longitude);

[self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];

[jsonString release];

}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

NSString *fileName = [[[NSURL URLWithString:kmlStr] path] lastPathComponent];
NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [pathArr objectAtIndex:0];

NSString *filePath = [folder stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];  

NSError *writeError = nil;

[webData writeToURL: fileURL options:0 error:&writeError];
if( writeError) {
    NSLog(@" Error in writing file %@' : \n %@ ", filePath , writeError );
    return;
}
NSLog(@"%@",fileURL);
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error !" message:@"Error has occured, please verify internet connection.."  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];

[alert show];
[alert release];
}

-(IBAction)showKmlData:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"KMLGenerator" ofType:@"kml"];

kml = [[KMLParser parseKMLAtPath:path] retain];

NSArray *overlays = [kml overlays];
[mapview addOverlays:overlays];

NSArray *annotations = [kml points];
[mapview addAnnotations:annotations];

MKMapRect flyTo = MKMapRectNull;
for (id <MKOverlay> overlay in overlays) {
    if (MKMapRectIsNull(flyTo)) {
        flyTo = [overlay boundingMapRect];
    } else {
        flyTo = MKMapRectUnion(flyTo, [overlay boundingMapRect]);
    }
}

for (id <MKAnnotation> annotation in annotations) {
    MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
    MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
    if (MKMapRectIsNull(flyTo)) {
        flyTo = pointRect;
    } else {
        flyTo = MKMapRectUnion(flyTo, pointRect);
    }
}

mapview.visibleMapRect = flyTo;
}

РЕДАКТИРОВАТЬ 2 Я сделал изменения, теперь он никуда не уходит, он падает, потому что не находит файл KMLGenerator.kml (путь)

-(void)showData 
{

NSString *url = /*kmlStr;*/@"http://www.ikub.al/hartav2/handlers/kmlgenerator.ashx?layerid=fc77a5e6-5985-4dd1-9309-f026d7349064&kml=1";
NSURL *path = [NSURL URLWithString:url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:path];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
theConnection = connection;
[connection release];
[request release];

}

//Search Coordinates for address entered in the searchBar
-(void) searchCoordinatesForAddress:(NSString *)inAddress
{
NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@?output=json",inAddress];

[urlString setString:[urlString stringByReplacingOccurrencesOfString:@" " withString:@"+"]];

NSURL *url = [NSURL URLWithString:urlString];

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

[connection release];
[request release];
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength:0]; //Here i get an alert: NSData may not respond to -setLength
                           //webData is a NSData object.
}


-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data]; //Here i get an alert: NSData may not respond to -appendData
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    if ( connection == theConnection ) //"theConnection" is for kml file download
    {
        NSString *fileName = [[[NSURL URLWithString:kmlStr] path] lastPathComponent];
        NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *folder = [pathArr objectAtIndex:0];

        NSString *filePath = [folder stringByAppendingPathComponent:fileName];
        NSURL *fileURL = [NSURL fileURLWithPath:filePath];  

        NSError *writeError = nil;

        [webData writeToURL: fileURL options:0 error:&writeError];

        if( writeError) {
            NSLog(@" Error in writing file %@' : \n %@ ", filePath , writeError );
            return;
        }

        NSLog(@"%@",fileURL);
    }
    else //it's a geocoding result
    {
        NSString *jsonString = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];

        NSDictionary *results = [jsonString JSONValue];

        //check the Google geocode error code before looking for coordinates...        
        NSDictionary *statusDict = [results objectForKey:@"Status"];
        NSNumber *errorCode = [statusDict objectForKey:@"code"];
        if ([errorCode intValue] == 200)  //200 is "success"
        {
            NSArray *placemark = [results objectForKey:@"Placemark"];
            NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"];

            double longitude = [[coordinates objectAtIndex:0] doubleValue];
            double latitude = [[coordinates objectAtIndex:1] doubleValue];

            NSLog(@"Latitude - Longitude: %f %f", latitude, longitude);

            [self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];
        }
        else
        {
            NSLog(@"geocoding error %@", errorCode);
        }

        [jsonString release];
    }
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!" message:@"Error has occured, please verify internet connection..." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}


- (IBAction)showKmlData:(id)sender
{

NSString *path = [[NSBundle mainBundle] pathForResource:@"KMLGenerator" ofType:@"kml"];

kml = [[KMLParser parseKMLAtPath:path] retain];

NSArray *annotationsImmut = [kml points];
NSMutableArray *annotations = [annotationsImmut mutableCopy];
//[mapview addAnnotations:annotations];
[self filterAnnotations:annotations];

MKMapRect flyTo = MKMapRectNull;

for (id <MKAnnotation> annotation in annotations) {
    MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
    MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
    if (MKMapRectIsNull(flyTo)) {
        flyTo = pointRect;
    } else {
        flyTo = MKMapRectUnion(flyTo, pointRect);
    }
}

mapview.visibleMapRect = flyTo;
}   

1 Ответ

1 голос
/ 13 ноября 2011

Все еще трудно определить причину, но есть некоторые проблемы с кодом, который вы выложили.

Во-первых, в didReceiveData эта строка, вероятно, не та, которую вы хотите:

if ( connection = theConnection ) //theConnection is created before

Одиночный = выполняет присваивание вместо проверки на равенство (что составляет ==).

Однако исправление этого не является решением (другая проблема в connectionDidFinishLoading).

Метод didReceiveData не подходит для обработки результатов геокодирования JSON.Метод didReceiveData может быть вызван несколько раз для одного запроса URL.Таким образом, возможно, что результаты геокодирования (так же, как файл kml) могут быть доставлены в несколько кусков, которые не могут быть обработаны по отдельности в этом методе.data в этом методе может быть частичным потоком полного результата, который не имеет смысла обрабатывать.Вам следует только добавлять данные в объект NSMutableData или, как предполагает ответ на связанный вопрос, записывать данные в файл.

Данные могут обрабатываться / анализироваться только методом connectionDidFinishLoading.

Поскольку вы используете один и тот же делегат соединения для загрузки файла kml и геокодирования, они оба вызывают один и тот же метод connectionDidFinishLoading.В этом методе вы не проверяете, к какому соединению оно вызывается.

Когда запрос URL геокодирования завершается и вызывает connectionDidFinishLoading, этот метод принимает все, что находится в webData (возможно, результаты геокодирования или пустыеданные) и записывает его в файл kmlStr.Вероятно, именно из-за этого данные kml показывают «ничего».

Необходимо переместить обработку результатов геокодирования на connectionDidFinishLoading и проверить, какое соединение вызывает его.

Дляпример:

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    if ( connection == theConnection ) //"theConnection" is for kml file download
    {
        NSString *fileName = [[[NSURL URLWithString:kmlStr] path] lastPathComponent];
        NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *folder = [pathArr objectAtIndex:0];

        NSString *filePath = [folder stringByAppendingPathComponent:fileName];
        NSURL *fileURL = [NSURL fileURLWithPath:filePath];  

        NSError *writeError = nil;

        [webData writeToURL: fileURL options:0 error:&writeError];
        if( writeError) {
            NSLog(@" Error in writing file %@' : \n %@ ", filePath , writeError );
            return;
        }
        NSLog(@"%@",fileURL);
    }
    else //it's a geocoding result
    {
        NSString *jsonString = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];

        NSDictionary *results = [jsonString JSONValue];

        //check the Google geocode error code before looking for coordinates...        
        NSDictionary *statusDict = [results objectForKey:@"Status"];
        NSNumber *errorCode = [statusDict objectForKey:@"code"];
        if ([errorCode intValue] == 200)  //200 is "success"
        {
            NSArray *placemark = [results objectForKey:@"Placemark"];
            NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"];

            double longitude = [[coordinates objectAtIndex:0] doubleValue];
            double latitude = [[coordinates objectAtIndex:1] doubleValue];

            NSLog(@"Latitude - Longitude: %f %f", latitude, longitude);

            [self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];
        }
        else
        {
            NSLog(@"geocoding error %@", errorCode);
        }

        [jsonString release];
    }
}

(Вероятно, лучше избегать использования одного и того же делегата для нескольких соединений. Было бы удобнее перенести геокодирование в другой класс с собственным объектом соединения и методами делегата. Кстати,В iOS5 встроено геокодирование, поэтому вам не нужно делать это самостоятельно. См. класс CLGeocoder .

Я добавил проверку для кода ошибки Google.Возможно, что запрашиваемый адрес не даст результатов, в этом случае не будет координат метки, и в этом случае широта и долгота будут установлены на ноль.Это еще одна возможная причина появления карты 0,0.

Похоже, вы используете устаревший геокодер Google v2 . Это самая последняя версия , но вы можете переключиться на использование CLGeocoder, если вам не требуется поддержка iOS4 или более ранней версии.

...